string array as parameter to plpgsql procedure - plpgsql

Can some one guide me how to test this procedure. (code got compiled but dont know if it is correct or not).
CREATE OR REPLACE PROCEDURE create_update_h( p_a_pkg_array CHARACTER VARYING [],p_u_pkg_array CHARACTER VARYING [] , inout out_error_code TEXT , inout out_error_text text )
LANGUAGE 'plpgsql'
calling with
do
$$
DECLARE out_error_code TEXT;
DECLARE out_error_text TEXT;
BEGIN
CALL create_update_h(
['t','t','t']::CHARACTER VARYING [],[result1,result2,result3]::CHARACTER VARYING [],out_error_code::TEXT,out_error_text::TEXT);
RAISE NOTICE 'myvar1 = %', out_error_code;
RAISE NOTICE 'mymsg1 = %', out_error_text;
END;
$$
giving error
ERROR: syntax error at or near "["
LINE 9: [t,t,t]::CHARACTER VARYING [],[result1,result2,result3]::CH...
^
SQL state: 42601
Character: 162
I tried the above script to test the proc . Could somebody tell me how to call a proceudre that has 2 arrays as input.

The syntax for array constructor in PostgreSQL is:
ARRAY[field, field ...]
The keyword ARRAY is mandatory

Related

Unit testing plpgsql procedure which has TYPE data

we have a TYPE t_string_array in our postgres database defined as character varying[].
We have a stored procedure which takes list of names and gives the result out in a cursor.
the procedure definition is
create or replace procedure test_lookup( in_speed t_string_array, inout display refcursor,
inout out_error_text TEXT);
I am trying to test this procedure with the block
do
$$
declare
display refcursor;
out_error_text text;
begin
call test_lookup(['Basic']::t_string_array,display::refcursor,out_error_text::text);
RAISE NOTICE 'mymsg1 = %', out_error_text;
RAISE NOTICE 'myvar1 = %', out_error_code;
END;
$$
I am getting error ERROR: syntax error at or near "["
I tried using call test_lookup('basic'::t_string_array,display::refcursor,out_error_text::text)
call test_lookup(array['basic']::character varying[],display::refcursor,out_error_text::text);
all gave me error.
Can you please suggest a way to test this procedure.

ERROR: syntax error at or near "END" when creating function

ERROR: syntax error at or near "END"
LINE 9: END;
^
SQL state: 42601
Character: 350
===========================
My procedure
CREATE OR REPLACE PROCEDURE proc_insert(empid bigint,ename character varying(256),
email character varying(256),enum bigint,
eadd bigint)
language 'plpgsql'
as $$
BEGIN
insert into proc_insert(empid,ename,email,enum,eadd)
END;
$$;
Missing semicolon after the command.
CREATE OR REPLACE PROCEDURE proc_insert(empid bigint
, ename varchar
, email varchar
, enum bigint
, eadd bigint)
LANGUAGE plpgsql AS
$proc$
BEGIN
INSERT INTO proc_insert -- add target column list!
VALUES(empid,ename,email,enum,eadd);
END
$proc$;
(While the one after END is optional.)
Plus, your INSERT statement was broken anyway. I fixed it, but you better add a target column list, too. See:
Cannot create stored procedure to insert data: type mismatch for serial column
You are getting this error because your insert query syntax is incorrect.
create or replace PROCEDURE proc_insert(empid bigint,ename character varying(256),
email character varying(256),enum bigint,
eadd bigint)
LANGUAGE plpgsql AS $$
declare
begin
insert into proc_insert values(empid,ename,email,enum,eadd);
end
$$;
Demo in DBfiddle

Postgresql function invocation

I've written a postgresql function shown as follows
CREATE OR REPLACE FUNCTION public."UpdateTx"(IN "instructionId" character varying,IN txdata character varying,IN txdetail character varying,IN txstatus character varying,IN resid character varying,IN "timestamp" bigint)
RETURNS character varying
LANGUAGE 'plpgsql'
VOLATILE
PARALLEL UNSAFE
COST 100
AS $BODY$DECLARE updateClause varchar;
BEGIN
IF instructionId = '' THEN
RAISE EXCEPTION 'instruction id is missing';
END IF;
IF txstatus = '' THEN
RAISE EXCEPTION 'tx status is missing';
END IF;
updateClause := CONCAT('txstatus= ', txstatus);
IF txData != '' THEN
updateClause = CONCAT(updateClause, ', ', 'txdata=', txdata);
END IF;
EXECUTE 'UPDATE transactions SET $1 WHERE instructionid=instructionid' USING updateClause;
END;
$BODY$;
So it expects 5 varchar & 1 bigint as input arguments.
I've tried to execute the following SQL query
Select UpdateTx('123'::varchar, 'test'::varchar, 'test'::varchar, 'test'::varchar, 'test2'::varchar, 4124::bigint)
but it keeps showing this error message
ERROR: function updatetx(character varying, character varying, character varying, character varying, character varying, bigint) does not exist
LINE 1: Select UpdateTx('123'::varchar, 'test'::varchar, 'test'::var...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
SQL state: 42883
Character: 8
Is the syntax incorrect?
Appreciate any suggestions or answers :)
Your immediate problem is that your function is declared as case-sensitive (with surrounding double quotes), but you call it in a case-insensitive manner (without the quotes, which, to Postgres, is equivalent to all lower caps). The names just do not match.
But there is more to it:
the way you pass variables is not OK; instead of concatenating part of the query into variable updateClause, you should pass a parameter for each value that needs to be passed to the variable - but better yet, you don't actually need dynamic SQL for this
Don't use variables that conflict with column names
I suspect that you want nulls instead of empty string (it makes much more sense to indicate the "lack" of a value)
the function needs to return something
I also notice that you are not using all arguments that are passed to function
Here is a function code, that, at least, compiles. You can start from there and adapt it to your exact requirement:
CREATE OR REPLACE FUNCTION public.UpdateTx(
IN pInstructionId character varying,
IN pTxdata character varying,
IN pTxdetail character varying, -- not used in the function
IN pTxstatus character varying,
IN pResid character varying, -- not used in the function
IN pTimestamp bigint - - not used in the function
)
RETURNS character varying
LANGUAGE plpgsql
VOLATILE
PARALLEL UNSAFE
COST 100
AS $BODY$
BEGIN
IF pInstructionId IS NULL THEN
RAISE EXCEPTION 'instruction id is missing';
END IF;
IF pTxstatus IS NULL THEN
RAISE EXCEPTION 'tx status is missing';
END IF;
UPDATE transactions
SET txstatus = pTxstatus, txData = COALESCE(pTxdata, txData)
WHERE instructionid = pInstructionId;
RETURN 1; -- put something more meaningful here
END;
$BODY$;
You would invoke it as follows:
select UpdateTx(
'123'::varchar,
'test'::varchar,
'test'::varchar,
'test'::varchar,
'test2'::varchar,
4124::bigint
)
Demo on DB Fiddle

How to concat two string in postgresql function?

I want a function which will return concated string. I am getting following error after execute this function in postgresql.
CREATE OR REPLACE FUNCTION getTableName ()
RETURNS text AS $$
DECLARE
state_short_name text;
BEGIN
state_short_name := (select lower(state_short_name) from mst_state where state_code in (SELECT substr(entity_code,1,2) FROM shg_detail_share WHERE entity_code = '3420006002001'))
RETURN (CONCAT(state_short_name, '_shg_detail'));
END;
$$ LANGUAGE plpgsql
I expect the output like 'jh_shg_detail' but I am getting error like this
ERROR: syntax error at or near "("
LINE 9: RETURN (CONCAT(state_short_name, '_shg_detail'));
You should use a select into in PL/pgSQL. And to avoid a name clash, don't name variables the same as columns:
CREATE OR REPLACE FUNCTION gettablename()
RETURNS text AS $$
DECLARE
l_state_short_name text;
BEGIN
select lower(state_short_name)
into l_state_short_name
from mst_state
where state_code in (SELECT substr(entity_code,1,2)
FROM shg_detail_share
WHERE entity_code = '3420006002001'));
RETURN CONCAT(state_short_name, '_shg_detail');
END;
$$ LANGUAGE plpgsql;
But you don't need PL/pgSQL for a simple SQL query like that. Your sub-query isn't really necessary as well. You can simplify that to where state_code = '34'
CREATE OR REPLACE FUNCTION gettablename()
RETURNS text
AS $$
select concat(lower(state_short_name), '_shg_detail')
from mst_state
where state_code = '34';
$$
LANGUAGE sql;
Your problem is a missing semicolon at the line with the assignment statement :=.
This makes the line that starts with RETURN (CONCAT a continuation line of the statement, and so you get the syntax error reported in that line.

How to declare variable and assign value into that in postgresql?

I'm very new in postgresql. I read many posts in this questions, but still don't get correct answer in my simple problem and keep receiving syntax error. I'm trying declare new string variable named parents_d and in the following lines trying to assign new value as well. Please help me!
CREATE OR REPLACE FUNCTION retrieve_parents(cid integer) RETURNS text AS $$
BEGIN
DECLARE pd text;
pd:= 'function';
RETURN concat(cid,pd);
END;
$$ LANGUAGE plpgsql;
ERROR: duplicate declaration at or near "pd"
LINE 4: pd:= 'function';
^
********** Error **********
ERROR: duplicate declaration at or near "pd"
SQL state: 42601
Character: 104
try like this
SQL Fiddle Demo
CREATE FUNCTION retrieve_parents(cid integer) RETURNS text AS $$
DECLARE pd text;
BEGIN
pd:= 'function';
RETURN concat(cid,pd);
END; $$
LANGUAGE PLPGSQL
I tried to do this as an edit, but the edit was rejected as being too small.
The problem you're running into is a misunderstanding of plpgsql's (somewhat confusing) block syntax. If you look on that page, the critical part you're missing is this:
[ DECLARE
declarations ]
There can be multiple declarations in a single DECLARE section. You can also nest blocks:
DECLARE
c_pi CONSTANT double precision := pi();
v_text text;
BEGIN
DECLARE
v_blah text;
BEGIN
NULL;
END;
END;
Note that the semicolon is optional on the outer-most block.