How to add value in enum in plpgsql function - postgresql

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;

Related

Postgresql update query syntax error in plpgsql function

I have to create a update procedure, so i created a function and given only below query
CREATE FUNCTION public.testf()
RETURNS boolean
LANGUAGE 'plpgsql'
AS $BODY$begin
update tt pp
set status = 'Ok'
return true;
end;$BODY$;
ALTER FUNCTION public.testf()
OWNER TO postgres;
returns error
ERROR: syntax error at or near "UPDATE" LINE 5: AS $BODY$UPDATE
return type I have given is int4range
What I am doing wrong
Please help
THanks
Pulling out my crystal ball, I see:
You created the function with LANGUAGE plpgsql.
You didn't surround the function body with BEGIN ... END;.
If your function is just a single SQL statement, use LANGUAGE sql.
Else, use the block-centered PL/pgSQL syntax properly.
You are missing an ; to end the UPDATE statement.
CREATE FUNCTION public.testf()
RETURNS boolean
LANGUAGE plpgsql
AS $BODY$
begin
update tt pp
set status = 'Ok'; --<< here
return true;
end;
$BODY$;

"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;

Using a parameter as return type in plpgsql function

Say I have this query:
CREATE OR REPLACE FUNCTION select_from_table(table_name varchar(63))
RETURNS SETOF table_name AS
$$
DECLARE
query TEXT := 'SELECT * FROM ' || table_name;
BEGIN
RETURN QUERY EXECUTE query;
END;
$$ LANGUAGE plpgsql;
Now if I try to execute it, I get error: type "table_name" does not exist and that's probably because I can only use the parameters within the function (between the dollar quotes) and not in the return type definition.
The question would be: are there any ways to SELECT from a table by passing its name as a parameter instead of hard coding it to the function? How?

syntax error when running postgresql function/stored procedure

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.

How to use EXECUTE FORMAT ... USING in postgres function

CREATE OR REPLACE FUNCTION dummytest_insert_trigger()
RETURNS trigger AS
$BODY$
DECLARE
v_partition_name VARCHAR(32);
BEGIN
IF NEW.datetime IS NOT NULL THEN
v_partition_name := 'dummyTest';
EXECUTE format('INSERT INTO %I VALUES ($1,$2)',v_partition_name)using NEW.id,NEW.datetime;
END IF;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION dummytest_insert_trigger()
OWNER TO postgres;
I'm trying to insert using
insert into dummyTest values(1,'2013-01-01 00:00:00+05:30');
But it's showing error as
ERROR: function format(unknown) does not exist
SQL state: 42883
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Context: PL/pgSQL function "dummytest_insert_trigger" line 8 at EXECUTE statement
I'm unable get the error.
Your function could look like this in Postgres 9.0 or later:
CREATE OR REPLACE FUNCTION dummytest_insert_trigger()
RETURNS trigger AS
$func$
DECLARE
v_partition_name text := quote_ident('dummyTest'); -- assign at declaration
BEGIN
IF NEW.datetime IS NOT NULL THEN
EXECUTE
'INSERT INTO ' || v_partition_name || ' VALUES ($1,$2)'
USING NEW.id, NEW.datetime;
END IF;
RETURN NULL; -- You sure about this?
END
$func$ LANGUAGE plpgsql;
About RETURN NULL:
To ignore result in BEFORE TRIGGER of PostgreSQL?
I would advice not to use mixed case identifiers. With format( .. %I ..) or quote_ident(), you'd get a table named "dummyTest", which you'll have to double quote for the rest of its existence. Related:
Are PostgreSQL column names case-sensitive?
Use lower case instead:
quote_ident('dummytest')
There is really no point in using dynamic SQL with EXECUTE as long as you have a static table name. But that's probably just the simplified example?
You need explicit cast to text:
EXECUTE format('INSERT INTO %I VALUES ($1,$2)'::text ,v_partition_name) using NEW.id,NEW.datetime;