syntax error when running postgresql function/stored procedure - postgresql

Trying to perform a set of complex Postgresql DB operations by using function, but even a simple function gets me error:
ERROR: syntax error at or near "text"
LINE 3: tmp text := info;
^
Here is SQL
CREATE or REPLACE FUNCTION createme (info text) RETURNS text AS $$
DECLARE
tmp text := info;
BEGIN
select :tmp
end
$$ LANGUAGE SQL;
Any idea why? Thx!

You procedure is not in SQL language, but it is in plpgsql language.
CREATE or REPLACE FUNCTION createme (info text) RETURNS text AS $$
DECLARE
tmp text := info;
BEGIN
RETURN tmp;
end
$$ LANGUAGE plpgsql;
SELECT :tmp is nonsense in this content. Functions returns a value with command RETURN - it is similar to any other environments.

Related

How to add value in enum in plpgsql function

So I have some simple function that should add value to an existing enum "profession" but instead of working it shows error
CREATE FUNCTION add_prof(p text) RETURNS VOID AS $$
BEGIN
ALTER TYPE profession ADD VALUE p;
RETURN;
END;
$$ LANGUAGE plpgsql;
The error is "[42601] syntax error". Btw, DataGrip shows that "string or IF expected but p."
Changing p to ' ' of course works fine but that's not what I need.
ALTER command is DDL command, and DDL commands doesn't allow an parametrization (they has not an execution plan). You need to use dynamic SQL:
CREATE FUNCTION add_prof(p text)
RETURNS VOID AS $$
BEGIN
EXECUTE format('ALTER TYPE profession ADD VALUE %L', p);
RETURN;
END;
$$ LANGUAGE plpgsql;

splitting characters using function in PostgreSQL

I tried to write function like this in PostgreSQL but I'm getting error like
ERROR: syntax error at or near "elems"
LINE 22: RETURN elems;
I want get output like
input: we###ty;rer##2hjjj
output:
we###ty
rer##2hjjj
please help me to solve this error
CREATE OR REPLACE FUNCTION public.fn_split(
inputstr text,
delimeter text)
RETURNS text[]
LANGUAGE 'plpgsql'
COST 100
VOLATILE SECURITY DEFINER PARALLEL UNSAFE
AS $BODY$
DECLARE
delimeter text;
elems text[];
var text;
arr_len int;
BEGIN
SELECT unnest(string_to_array(inputstr,delimeter))
INTO elems
RETURN elems;
END
$BODY$;
CREATE OR REPLACE FUNCTION public.fn_split(
inputstr text,
delimeter text)
RETURNS text[]
LANGUAGE 'plpgsql'
COST 100
VOLATILE SECURITY DEFINER
AS $BODY$
DECLARE
elems text[];
BEGIN
SELECT string_to_array(inputstr,delimeter) INTO elems;
RETURN elems;
END;
$BODY$;
Now call this function like this
SELECT UNNEST(fn_split('1,2,3',',')) as retval
Above is the screenshot which includes function definition and in the first list the command to call this function
Here is the command that you need to execute in order to call this function in the PostgreSQL query window after the creation of the function.
Your function is defined to return an array, however unnest would turn the result of creating the array into rows of strings. There is also no need to duplicate the parameter definition as local variables in a DECLARE block. And as you don't seem to want to manipulate the created array somehow, there is no need to store it in a local variable.
It seems you just want:
CREATE OR REPLACE FUNCTION public.fn_split(
inputstr text,
delimeter text)
RETURNS text[]
LANGUAGE plpgsql
immutable
AS $BODY$
BEGIN
return string_to_array(inputstr,delimeter);
END
$BODY$;
Or simpler as a SQL function:
CREATE OR REPLACE FUNCTION public.fn_split(
inputstr text,
delimeter text)
RETURNS text[]
LANGUAGE sql
immutable
AS
$BODY$
select string_to_array(inputstr,delimeter);
$BODY$;
Note that the language name is an identifier and should not be enclosed in single quotes. This syntax is deprecated and support for it will be removed in a future Postgres version.
Edit:
It seems you don't actually want an array, but one row per element after splitting the input value. In that case the function should be declared as returns table() not returns text[]
CREATE OR REPLACE FUNCTION public.fn_split(
inputstr text,
delimeter text)
RETURNS table(element text)
LANGUAGE sql
immutable
AS
$BODY$
select unnest(string_to_array(inputstr,delimeter));
$BODY$;
Then use it like this:
select *
from fn_split('we###ty;rer##2hjjj', ';');
Since Postgres 14
select unnest(string_to_array(inputstr,delimeter));
can be simplified to
select string_to_table(inputstr,delimeter);

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.

"query has no destination for result data" error even after having return in the function

Below is my function, even after having a RETURN statement, but a
query has no destination for result data
error is thrown. Am I missing something?
CREATE OR REPLACE FUNCTION test(ulds character varying)
RETURNS boolean AS
$BODY$
DECLARE
val_result boolean;
BEGIN
select * from regexp_split_to_array('BLK&AAK&AKE', '&');
SET val_result = false;
RETURN val_result;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION test(character varying)
There are more than one issues:
Result of unbind queries is not result of function in Postgres. You need to use INTO clause.
regexp_split_to_array is scalar function, there is not any reason to call this function from SELECT statement. Use SELECT only when you take result of table function, or when you need to read data from relations.
assign statement in plpgsql is based on := symbol. The command SET is used for something different.
the type text is proffered against varchar for function's parameters.
So your code can looks like:
CREATE OR REPLACE FUNCTION test(ulds text)
RETURNS boolean AS $$
DECLARE
result boolean;
target text[];
BEGIN
-- suboptimal, don't do this!!!
SELECT regexp_split_to_array('BLK&AAK&AKE', '&') INTO target;
-- preferred
target := regexp_split_to_array('BLK&AAK&AKE', '&');
result := true;
RETURN result;
END;
$$ LANGUAGE plpgsql;

Dollar-quotes failing with JDBC

I have to write a function in PLPGSQL but I have problem with the function body quoted with dollar-quoting. Using the first tutorial:
CREATE FUNCTION inc(val integer)
RETURNS integer AS
$BODY$
BEGIN
RETURN val + 1;
END;
$BODY$
LANGUAGE PLPGSQL;
I get an error:
unterminated dollar-quoted string at or near $$
Searching on google I just found it's a JDBC Driver problem but I cannot update it.
So I have tried to change the DELIMITER to remove $$:
DELIMITER ++;
CREATE FUNCTION inc(val integer)
RETURNS integer AS
++BODY++
BEGIN
RETURN val + 1;
END;
++BODY++
LANGUAGE PLPGSQL;
DELIMITER ;
The command doesn't return any error but function doesn't exists when I try to call it:
select inc(4);
What am I missing?
The underlying problem is JDBC's inability to deal with dollar-quotes.
I think this was fixed with JDBC version 9.4.1208 (2016-02-16).
See:
Exceptions when creating a trigger in PostgreSQL 9.1
How to execute plpgsql anonymous block in Oracle SQL Developer?
You can avoid the problem by using plain quotes for the simple case:
CREATE FUNCTION inc(val integer)
RETURNS integer AS
'
BEGIN
RETURN val + 1;
END
' LANGUAGE plpgsql;
See:
What are '$$' used for in PL/pgSQL
Insert text with single quotes in PostgreSQL