I have a stored procedure writen in T-SQL and I want to make it for PostgreSQL but I'm not so familiar with PostgreSQL.
My stored procedure look like this:
CREATE PROCEDURE usp_insert_allocated_time
#fld_project_id INT,
#fld_allocated_time INT
AS
DECLARE #project int;
SET #project = #fld_project_id;
DECLARE #allocated int;
DECLARE #time int;
BEGIN
SET #time = (SELECT SUM(fld_allocated_time)
FROM dbo.tbl_project_timesheet
WHERE fld_project_id =#project)
SET #allocated = (SELECT fld_allocated_days FROM dbo.tbl_project where fld_id = #project);
IF #allocated > #time
BEGIN
INSERT into dbo.tbl_project_timesheet(fld_project_id,fld_allocated_time)
VALUES(#fld_project_id,#fld_allocated_time);
END
ELSE
PRINT 'Not OK';
END
And I have to do something like this, but on line 10 I get this error:
ERROR: invalid input syntax for integer: "293.00"
SQL state: 22P02
Context: PL/pgSQL function
"SA_PRJ".usp_add_timesheet_record_new(integer,integer,numeric,numeric,character varying,character varying) line 10 at assignment
CREATE OR REPLACE FUNCTION "SA_PRJ".usp_add_timesheet_record_new(p_uid integer, p_project_id integer, p_allocated_time numeric, p_achieved_time numeric, p_task_desc character varying, p_obs character varying)
RETURNS void AS
$BODY$
declare alloc_id integer;
declare project integer;
declare allocated integer;
declare allocated_time integer;
BEGIN
project := p_project_id;
allocated_time := (SELECT SUM(fld_allocated_time)
FROM "SD_PRJ".tbl_project_timesheet
WHERE fld_project_id = project);
allocated := (SELECT fld_allocated_days FROM "SD_PRJ".tbl_project where fld_id = project);
if not "SA_ADM".usp_check_permission(p_uid, 'SA_PRJ', 'usp_add_timesheet_record') then
raise exception 'User ID % no have the permission!', p_uid;
end if;
select fld_id into alloc_id from "SD_PRJ".tbl_project_allocation where fld_emp_id = p_uid and fld_project_id = p_project_id;
BEGIN
IF (allocated > allocated_time) THEN
INSERT INTO "SD_PRJ".tbl_project_timesheet(fld_emp_id, fld_project_id, fld_is_allocated,fld_allocated_time, fld_achieved_time, fld_task_desc, fld_obs)
VALUES (p_uid,p_project_id,coalesce(alloc_id,0), p_allocated_time, p_achieved_time,p_task_desc, p_obs);
ELSE
RAISE NOTICE 'Not OK!!';
END IF;
END;
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
It's more complex version in PostgreSQL for what I want.
You don't really give enough information to try and fix your problem, but the error message is pretty descriptive. You are trying to put 293.00 into an integer. Here I can reproduce:
DO
$$
DECLARE
i INT;
BEGIN
i := 293.00;
RAISE NOTICE 'i=%', i;
END
$$;
This will raise:
ERROR: invalid input syntax for integer: "293.00"
SQL state: 22P02
Context: PL/pgSQL function inline_code_block line 6 at assignment
You need to change your variable to the same datatype as the data you are trying to assign to it. For example:
DO
$$
DECLARE
i NUMERIC(5, 2);
BEGIN
i := 293.00;
RAISE NOTICE 'i=%', i;
END
$$;
This works and outputs:
NOTICE: i=293.00
Query returned successfully with no result in 14 ms.
Related
I try to run in snowflake the following sql stored procedure with a declare variable inside but i got the following error : Error: Bind variable for object MYTABLE AS MYTABLE not set (line 13).
when I hard code the value into the function identifier it's work by the way...
CREATE OR REPLACE PROCEDURE DBNAME.SCHEMANAME."SP_test"()
RETURNS varchar
LANGUAGE SQL
EXECUTE AS CALLER
AS
declare
MYTABLE varchar := 'DBNAME.SCHEMANAME.TABLENAME';
--MYRESULT varchar;
BEGIN
-- let MYTABLE varchar := 'DBNAME.SCHEMANAME.TABLENAME';
-- MYTABLE := 'DBNAME.SCHEMANAME.TABLENAME';
--filter to return 1 row
-- let MYRESULT varchar := ( select col1 from IDENTIFIER( 'DBNAME.SCHEMANAME.TABLENAME' ) where col2=2 ) ;
--ko
let MYRESULT varchar := ( select col1 from IDENTIFIER( :MYTABLE ) where col2=2 ) ;
return :MYRESULT;
end;
This works for me:
CREATE OR REPLACE PROCEDURE "SP_test"()
RETURNS varchar
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
declare
MYRESULT resultset;
MYTABLE varchar := 'SERGIU_TESTDB.PUBLIC.CITIBIKE_TRIPS';
MYVAL varchar;
BEGIN
MYRESULT := (select ride_id from identifier(:MYTABLE) limit 1);
let c1 cursor for MYRESULT;
for row_variable in c1 do
MYVAL := row_variable.ride_id;
end for;
return MYVAL;
END
$$;
Calling it:
CALL "SP_test"();
I get a value out of it:
B1CE81D802D68DF8
Is there a way to build a select statement in oracle using values stored in variables?
For example can you do this:
declare
tbl_var varchar2(10) := "map_set";
begin
select count(*) from tbl_var;
end;
Yes there is, using execute immediate:
declare
tbl_var varchar2(10) := 'map_set';
result number;
begin
execute immediate 'select count(*) from '||tbl_var into result; --save result into variable
dbms_output.put_line('Total rows:'||result); --print result
end;
Second way, you can create a function that receives table name as parameter and return the count:
create function get_count(tbl_var varchar2) return number is
result number;
begin
execute immediate 'select count(*) from '||tbl_var into result;
return result;
end;
After create the function you can query it like this:
select get_count('map_set') from dual;
hello programmers i'm writing a TSQL in-line table function, actually im not good enough in sql, when i finished my code i've got this error "Incorrect syntax near 'BEGIN'." , anyone know the solution please give it to me.
by the way when i clicked double-click over the error msg it's selected the last "end"
create FUNCTION [dbo].[CheckLogin]
(
#un varchar(max),
#pw varchar(max)
)
RETURNS TABLE
AS
begin
declare #unexist int, #unpwmatch int, #uid bigint
declare #uisactivated bit , #uisdeleted bit
-----
set #unexist = (select COUNT(UserAccessInfo.UserId) FROM UsersAccessInfo
WHERE UserAccessInfo.UserName = #un OR UserAccessInfo.UserEmail = #un)
------
set #unpwmatch = (select count(usersaccessinfo.userid) from usersaccesinfo
WHERE (usersaccessinfo.UserName = #un) AND (usersaccessinfo.UserPassword = #pw) OR
(usersaccessinfo.UserEmail = #un) AND (usersaccessinfo.UserPassword = #pw))
------
set #uid =(select usersaccessinfo.userid from usersaccessinfo where
serAccessInfo.UserName = #un OR UserAccessInfo.UserEmail = #un)
------
if #uid <> Null
begin
set #uisactivated =(select usersaccessinfo.userisactivated from usersaccessinfo
where usersaccessinfo.userid=#uid)
end
------
if #uid <> null
begin
set #uisactivated =(select usersaccessinfo.userisactivated from usersaccessinfo
where usersaccessinfo.userid=#uid)
end
------
if #unexist = 0
begin
select dbo.getreportbyid('1004')
end;
else if #unpwmatch = 0
begin
select dbo.getreportbyid('1005')
end;
else if #uid<>0
begin
if #uisactivated =0
begin
select dbo.getreportbyid('1002')
end;
else if #uisdeleted = 1
begin
select dbo.getreportbyid('1003')
end;
end;
else
begin
select ('successful') as report
end;
return
end;
The problem is these lines:
...
RETURNS TABLE
AS
...
This is not valid syntax for any of the four types of user-defined functions.
Assuming that you are trying to define a multi-statement table-valued function, it should look like this:
...
RETURNS #YourTableName TABLE( <column-definitions>... )
AS
...
And then your function statements should be putting the function return data into that table before it executes the RETURN statement, which it also is not doing.
Your problem is that you are mixing the syntax of multi-statement table valued functions and inline table valued functions. For examples of each and some performance considerations check out my post here: http://sqlity.net/en/498/t-sql-tuesday-24-prox-n-funx/
In short, if you want to use multiple statements within a table valued function you have to declare a table variable after the RETURNS keyword and insert the rows you want to return in there in the function body. However, this type of function has serious performance implications and you should try hard to stay away from it.
Besides of that, you seem to have mismatching BEGINs and ENDs. As Barry said, "A little indentation would go a long way here" in helping you and others understand you code better.
You cannot have ; before the if command end. Also null checing is wrong. For ex;
if #uid <> null -- (1) note: should be if #uid is not null
Begin
-- query
End; --(2)-Note: this is wrong
Else
Begin
--Query
End
This is my stored procedure I am trying to create:
CREATE PROCEDURE [cih_owner].[UpdateDisplayOrder]
#CbpTableName varchar (21),
#CbpObjId int,
#CbpId int,
#DisplayOrder int
AS
BEGIN
IF (#CbpTableName = "CbpActivity")
BEGIN
UPDATE [cih_owner].[CbpActivity] SET DisplayOrder = #DisplayOrder WHERE Id = #CbpObjId AND CbpId = #CbpId
;
END
END
GO
However, in line that reads:
(#CbpTableName = "CbpActivity")
I get squigglies under
"CbpActivity"
with the error
Invalid column name 'CbpActivity'
All I am trying to do is compare a string that I sent to the stored procedure.
Thanks!
You need to use apostrophes instead of quotations for string literals:
IF (#CbpTableName = 'CbpActivity')
Have you tried to modified the " for ' like this:
CREATE PROCEDURE [cih_owner].[UpdateDisplayOrder]
#CbpTableName varchar (21),
#CbpObjId int,
#CbpId int,
#DisplayOrder int
AS
BEGIN
IF (#CbpTableName = 'CbpActivity')
BEGIN
UPDATE [cih_owner].[CbpActivity] SET DisplayOrder = #DisplayOrder WHERE Id = #CbpObjId AND CbpId = #CbpId
GO
END
END
GO
You should be using single quote
IF (#CbpTableName = 'CbpActivity')
String are enclosed in single quotes in SQL
I need to convert a comma separated text into a set of records. I created this function
but I am not convinced that the best way:
CREATE OR REPLACE FUNCTION F_StringListToRecord(pStringList TEXT, pDelimiter VARCHAR(10)) RETURNS SETOF RECORD AS $$
DECLARE
vIndex INT;
arrSize INT;
arrValue TEXT[];
BEGIN
arrValue := STRING_TO_ARRAY(pStringList, pDelimiter);
arrSize := ARRAY_UPPER(arrValue, 1);
FOR vIndex IN 1..arrSize LOOP
RETURN QUERY SELECT arrValue[vIndex];
END LOOP;
END $$
LANGUAGE plpgsql;
Is there any other function similar to STRING_TO_ARRAY (perhaps STRING_TO_RECORD)?
In 8.4 you can use:
select * from unnest(string_to_array(my_string_here,delimiter)) as v(x);