Return ResultSet in pgsql function - postgresql

I have the function below...
CREATE OR REPLACE FUNCTION class_listing(var_sem integer, var_sy character) RETURNS SETOF RECORD AS
DECLARE
current_offering record;
BEGIN
SELECT subcode, offerno INTO current_offering FROM offering WHERE SY=var_sem AND SEM=var_sy;
END;
How to return current_offering as resultset?

You can use a SQL or PLpgSQL functions. Using anonymous records as returning type is not practical (mainly it is not friendly, when you write queries). Use RETURNS TABLE or OUT parameters instead.
CREATE OR REPLACE FUNCTION class_listing(var_sem integer, var_sy varchar)
RETURNS TABLE (subcode varchar, offerno int) AS $$
BEGIN
RETURN QUERY SELECT o.subcode, o.offerno
FROM offering
WHERE SY=var_sem AND SEM=var_sy;
END;
$$ LANGUAGE plpgsql;
or SQL language
CREATE OR REPLACE FUNCTION class_listing(var_sem integer, var_sy varchar)
RETURNS TABLE (subcode varchar, offerno int) AS $$
SELECT o.subcode, o.offerno
FROM offering
WHERE SY=$1 AND SEM=$2;
$$ LANGUAGE sql;
Attentions - query based functions works (with small exception) as optimizer barrier. So be careful when you use it in complex queries.
For completeness - your example can be written as:
CREATE OR REPLACE FUNCTION class_listing(var_sem integer, var_sy varchar)
RETURNS SETOF RECORD AS $$
DECLARE current_offering record;
BEGIN
FOR current_offering IN
SELECT o.subcode, o.offerno
FROM offering
WHERE SY=var_sem AND SEM=var_sy;
LOOP
RETURN NEXT current_offering;
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql;
But this form is deprecated now

Related

Select Statement using Stored Procedure

May I ask on how to call a method when the content of the stored procedure is about select statement? (Using postgreSQL)
CREATE OR REPLACE PROCEDURE select_table(table_name VARCHAR(255))
language plpgsql
as $$
BEGIN
EXECUTE('SELECT * FROM' || ' ' || quote_ident(table_name));
END $$;
CALL select_table('employee_table');
EDITED(USING FUNCTION)
CREATE OR REPLACE FUNCTION select_table(table_name VARCHAR(255))
language plpgsql
as $$
BEGIN
SELECT * FROM table_name
RETURN table_name;
END $$;
In PostgreSQL procedures doesn't execute any select statements and doesn't have return.
For returning data you can use functions. But functions also cannot return different structural data, examples:
CREATE OR REPLACE FUNCTION fr_test()
RETURNS TABLE(id integer, bookname character varying)
LANGUAGE plpgsql
AS $function$
begin
return QUERY
SELECT tb.id, tb.bookname from rbac.books tb;
end;
$function$
;
or
CREATE OR REPLACE FUNCTION fr_test()
RETURNS setof public.books
LANGUAGE plpgsql
AS $function$
begin
return QUERY
SELECT * from public.books;
end;
$function$
;
But for returning difference tables you can do it using procedures and using out refcursor, like as in Oracle. For example:
create or replace procedure pr_test(OUT r1 refcursor)
as $$
begin
open r1 for
select * from public.books;
end;
$$ language plpgsql;

Create a stored procedure to Delete Records postgres

I have created a function to delete multiple records.In our table contain id as type uuid.
We get the input is like array of ids.
CREATE OR REPLACE FUNCTION public.deletetVersion(item_list uuid[])
RETURNS TABLE(id uuid[])
LANGUAGE 'plpgsql'
COST 100
VOLATILE PARALLEL UNSAFE
ROWS 1000
AS $BODY$
BEGIN
RETURN QUERY
DELETE FROM version WHERE id = ANY(item_list);
END;
$BODY$;
SELECT * from deletetVersion(Array['b6ad1912-e4f1-4419-831a-c70df89ffd63','877898f0-2f3f-4890-a658-898e35ffee3a'])
But i got an error like:
Anyone please help me
ERROR: function deletetversion(text[]) does not exist
it is because the
Array['b6ad1912-e4f1-4419-831a-c70df89ffd63','877898f0-2f3f-4890-a658-898e35ffee3a']
is treated as text[]
try the following
Array['b6ad1912-e4f1-4419-831a-c70df89ffd63'::uuid,'877898f0-2f3f-4890-a658-898e35ffee3a'::uuid]
as a parameter to your function
for example
CREATE OR REPLACE FUNCTION public.test_uuid(item_list uuid[])
RETURNS TABLE(id uuid[])
LANGUAGE 'plpgsql'
COST 100
VOLATILE PARALLEL UNSAFE
ROWS 1000
AS $BODY$
BEGIN
RETURN QUERY
SELECT item_list;
END;
$BODY$;
SELECT * from test_uuid(Array['b6ad1912-e4f1-4419-831a-c70df89ffd63'::uuid])
In case of deletion
CREATE OR REPLACE FUNCTION public.test_uuid(item_list uuid[])
RETURNS VOID
LANGUAGE 'plpgsql'
COST 100
VOLATILE PARALLEL UNSAFE
ROWS 1000
AS $BODY$
BEGIN
RETURN QUERY
DELETE from tableName WHERE id = ANY(item_list);
END;
$BODY$;
Your function should return either setof uuid - i.e. a table of uuid-s - or uuid[]. I would prefer the first. You do not need PL/pgSQL, plain SQL is enough. So the function is:
create or replace function public.deletetVersion(item_list uuid[])
returns setof uuid language 'sql' as
$$
delete from version where id = any(item_list) returning id;
$$;
The version returning an array is a bit more complex:
create or replace function public.deletetVersion(item_list uuid[])
returns uuid[] language 'sql' as
$$
with t(d_id) as
(
delete from version where id = any(item_list) returning id
)
select array_agg(d_id) from t;
$$;
And - as #Ibrahimshamma says - you may need to cast the argument to uuid[].

Return table in stored procedure postgresql

I want to return the whole table with stored procedure not function
my code is:
CREATE OR REPLACE PROCEDURE public.test()
RETURN TABLE (
id numeric
, test varchar
) AS -- Results -- remove this
$func$
BEGIN
RETURN QUERY
SELECT *
FROM public.test
END
$func$ LANGUAGE plpgsql;
but its not works.
Stored procedures aren't meant to return anything, use a function. And you don't need PL/pgSQL for that either:
create or replace FUNCTION public.test()
returns TABLE (id numeric, test varchar)
AS
$func$
SELECT *
FROM public.test;
$func$
LANGUAGE sql;
As you return all columns of one table, you can also use returns setof
create or replace FUNCTION public.test()
returns setof public.test
AS
$func$
SELECT *
FROM public.test;
$func$
LANGUAGE sql;
Then use it like a table:
select *
from test();

How to get entire table data or multiple rows returned from a function in PG/PLSQL with pgAdmin 4.2.?

I tried using setof and table. While creating function in pgAdmin 4.2 there is no return type called setof or table. If I create function with setof and table name as a selected return type, it only returns one row of table.
CREATE FUNCTION pgsql_returnrecords() RETURNS SETOF RECORD(name char, city, char, id integer) AS
$BODY$
DECLARE
rec RECORD;
BEGIN
select name,city,id INTO rec from test;
return next rec;
END;
$BODY$ language plpgsql;
I want my function to return table data with all rows and columns.
It's either returns setof record or returns table(....) or setof table_name With returns setof record you have to specify the column names when using the function.
You are also not returning a complete result, because you only fetch a single row, put it into the record and return that. To return a real "set" you need to use return query in PL/pgSQL. But such a function is much better written as a SQL function:
CREATE FUNCTION pgsql_returnrecords()
RETURNS table(name text, city text, id integer)
AS
$BODY$
select name,city,id
from test;
$BODY$
language sql;
If you want to always return a complete row from the table test you can simplify that using returns setof test instead of returns table(..)
CREATE FUNCTION pgsql_returnrecords()
RETURNS setof test
AS
$BODY$
select *
from test;
$BODY$ language sql;
Or, if you insist on PL/pgSQL:
CREATE FUNCTION pgsql_returnrecords()
RETURNS table(name text, city text, id integer)
AS
$BODY$
BEGIN
return query
select name,city,id
from test;
END;
$BODY$
language plpgsql;
In both cases you have to use the function like a table in the FROM clause:
select *
from pgsql_returnrecords() ;

PostgreSQL - Function that returns labels of any ENUM

I am trying to write a "generic" function that will return labels of any enum (in any schema)...
But I am not having much luck because I am not sure what should argument type be...
The goal would be to be able to call function like this
SELECT common.get_enum_labels('public.rainbow_colors');
SELECT common.get_enum_labels('audit.user_actions');
This is what I have so
CREATE OR REPLACE FUNCTION common.get_enum_labels(enum_name regtype)
RETURNS SETOF text AS
$$
BEGIN
EXECUTE format('SELECT unnest(enum_range(NULL::%s))::text AS enum_labels ORDER BY 1', enum_name);
END;
$$
LANGUAGE plpgsql
STABLE
PARALLEL SAFE
;
Any tips would be appreciated
The argument type should be regtype, do not forget to return something from the function
CREATE OR REPLACE FUNCTION get_enum_labels(enum_name regtype)
RETURNS SETOF text AS
$$
BEGIN
RETURN QUERY
EXECUTE format('SELECT unnest(enum_range(NULL::%s))::text ORDER BY 1', enum_name);
END;
$$
LANGUAGE plpgsql
create or replace function get_enum_labels(enum_name regtype)
returns setof text language sql stable
as $$
select enumlabel::text
from pg_enum
where enumtypid = enum_name
order by enumsortorder
$$;