My first function consumes an array of UUID and returns a set of rows from the table:
CREATE OR REPLACE FUNCTION fun1 (
"UUID_" uuid []
)
RETURNS SETOF service AS
$body$
with recursive tree as (
SELECT * FROM service
WHERE id = ANY($1)
UNION ALL
SELECT service.* FROM service
JOIN tree ON service.id = tree.parent_id)
select distinct * from tree;
$body$
LANGUAGE 'sql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100 ROWS 1000;
For now I want to write another one to consume list of UUID as varchar and return the same data as the first function.
My bad try :
CREATE OR REPLACE FUNCTION fun2 (
"UUID_" varchar
)
RETURNS TABLE (
"ID" uuid,
"NAME" varchar,
"PARENT_ID" uuid
) AS
$body$
BEGIN
RETURN QUERY
with recursive tree as (
SELECT * FROM service
WHERE id = ANY(string_to_array($1, ',')::UUID[])
UNION ALL
SELECT service.* FROM service
JOIN tree ON service.id = tree.parent_id)
select distinct(ID), name, parent_id from tree;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100 ROWS 1000;
I'll answer by myself :
function fun1 can use varchar with converting to array of UUID when I use it.
so I can write :
select * from fun1('{some UUID array as varchar}'::UUID[]);
Related
That search function takes name, pageno, pagesize as input
It will return table as cursor and totalCount as bigint.
but it is returning 2 output in a single column like this:
CREATE OR REPLACE FUNCTION public.search(
name text,
pagenumber integer,
pagesize integer)
RETURNS Table (totalCount bigint, ref1 refcursor)
LANGUAGE 'plpgsql'
COST 100
VOLATILE PARALLEL UNSAFE
ROWS 1000
AS $BODY$
DECLARE
ref1 refcursor:= 'ref1';
begin
open ref1 for
SELECT * FROM table d
where
d."name" = name
ORDER BY d."name" ,d."DrugName" ASC
LIMIT PageSize
OFFSET ((PageNumber-1) * PageSize);
RETURN QUERY
select (select count(*)
FROM table d
where d."name" = name), ref1;
end;
$BODY$;
ALTER FUNCTION public.search(text, integer, integer)
OWNER TO postgres;
this is so far i have tried. I want to view this as a table containing two columns column_count , column_cursor
I'm using postgresql 14 and trying to return an entire record from a table in addition to columns from different tables. The catch is, that I don't want to write all the titles in the record. I tried working with the guide lines here [1], but I'm getting different errors. Can anyone tell me what I'm doing wrong?
CREATE OR REPLACE FUNCTION public.get_license_by_id(license_id_ integer)
RETURNS TABLE(rec tbl_licenses, template_name character varying, company_name character varying)
LANGUAGE 'plpgsql'
COST 100
VOLATILE SECURITY DEFINER PARALLEL UNSAFE
ROWS 1000
AS $BODY$
DECLARE
BEGIN
CREATE TEMPORARY TABLE tempTable AS (
SELECT
(rec).*, B.company_name, C.template_name
-- Tried using A instead of (rec).* with error: column "a" has pseudo-type record
FROM
(
(SELECT * FROM tbl_licenses) A
LEFT JOIN
(SELECT * FROM tbl_customers) B on A.customer_id = B.customer_id
LEFT JOIN
(SELECT * FROM tbl_templates) C on A.template_id = C.template_id
)
);
UPDATE tempTable
SET license = '1'
WHERE tempTable.license IS NOT NULL;
RETURN QUERY (
SELECT * FROM tempTable
);
DROP TABLE tempTable;
RETURN;
END;
$BODY$;
I'm calling the function like SELECT rec FROM get_license_by_id(1);
but getting:
ERROR: structure of query does not match function result type
DETAIL: Returned type integer does not match expected type tbl_licenses in column 1.
You need to cast the A alias to the correct record type. However the nested derived tables are not necessary for the other tables. If you use a coalesce() for the license column in the SELECT, then you get get rid of the inefficient creation and update of the temp table as well.
CREATE OR REPLACE FUNCTION get_license_by_id(license_id_ integer)
RETURNS TABLE(rec tbl_licenses, template_name character varying, company_name character varying)
LANGUAGE sql
STABLE
AS $BODY$
SELECT a::tbl_licenses, -- this is important
B.company_name, C.template_name
FROM (
select license_id, customer_id, ... other columns ...,
coalesce(license, '1') as license -- makes the temp table unnecessary
from tbl_licenses A
) a
LEFT JOIN tbl_customers B on A.customer_id = B.customer_id
LEFT JOIN tbl_templates C on A.template_id = C.template_id
where a.license_id = license_id_;
$BODY$
;
I have a query that I use in different parts of a system. Now I want to make a function wherein it accepts a text to be used as a query, I'm not even sure if this is possible. However, I want to know if there's a possible workaround for this.
What I want to achieve is a function that returns a table and accepts a text/varchar that could be used as a query.
Here's what I have, I have a query that is kind of a "base query" that can have different data based on the given CTE which is named:
data_table
refer to the function and its usage below - this is mostly abstract but imo this should be enough.
CREATE OR REPLACE FUNCTION func(
data_query TEXT
)
RETURNS TABLE
(
id BIGINT,
random_text varchar
)
LANGUAGE plpgsql
AS $function$
BEGIN
RETURN QUERY
with data_table AS (
data_query
), another_data_table AS (
SELECT
*
FROM my_data
)
SELECT
d.id,
ad.random_text
FROM data_table d
INNER JOIN another_data_table ad
ON ad.ref_id = d.id;
END; $function$;
usage:
SELECT * FROM func('SELECT * FROM my_data_table');
SELECT * FROM func('SELECT * FROM my_second_data_table');
Instead of passing the query, you may pass the table name and access it dyamically in your query using EXECUTE format
CREATE OR REPLACE FUNCTION func(
table_name_in TEXT
)
RETURNS TABLE
(
id BIGINT,
random_text varchar
)
LANGUAGE plpgsql
AS $function$
BEGIN
RETURN QUERY EXECUTE format (
'SELECT
d.id :: bigint,
ad.random_text :: varchar
FROM %I d
INNER JOIN my_data ad
ON ad.ref_id = d.id', table_name_in );
END
$function$;
usage:
SELECT * FROM func('my_data_table');
SELECT * FROM func('my_second_data_table');
I'm trying to use a plgSQL witch return me a record type :
CREATE FUNCTION actu(id INTEGER) RETURNS RECORD AS $$
DECLARE
ret RECORD;
BEGIN
SELECT id_photo, id_user, lien, titre
FROM photo
WHERE id_user IN (
SELECT id_userabo
FROM abo
WHERE id_user = id )
ORDER BY date_publi DESC LIMIT 10;
RETURN ret;
END;$$
LANGUAGE plpgsql;
When I'm trying to use it with :
SELECT * FROM actu(4)
AS (id_photo Integer, id_photo Integer, lien Varchar, titre Varchar);
pgAdmin4 send me error :
ERROR: ERROR: the request has no destination for the resulting data
HINT: If you want to cancel the results of a SELECT, use PERFORM instead.
CONTEXT: PL/pgsql function fil_actu(integer), line 5 with SQL statement
The immediate error is, that the result of a select statement needs to be stored somewhere (that's what the error says). You would need to use select .. into ret from ... to store the result, but that wouldn't work as a variable of type record can only store one row from a result.
You apparently want to return more than just one row, so you need to define the function as returns table() and then use return query in PL/pgSQL to return the result of a query. But for a simple function encapsulating a SELECT query, a language sql function is more efficient.
CREATE FUNCTION actu(id INTEGER)
-- adjust the data types for the returned columns!
RETURNS table (id_photo int, id_user int, lien text, titre text)
AS $$
SELECT id_photo, id_user, lien, titre
FROM photo
WHERE id_user IN (SELECT id_userabo
FROM abo
WHERE id_user = id )
ORDER BY date_publi DESC
LIMIT 10;
$$
LANGUAGE sql;
You can use that function like this:
select *
from actu(42);
You may define those types inside the function, but with different names for the types. The return type can be a TABLE type and use RETURN QUERY to return the results.
CREATE FUNCTION actu(id INTEGER) RETURNS TABLE
(typ_id_photo Integer, typ_id_user Integer, typ_lien Varchar, typ_titre Varchar)
AS $$
BEGIN
RETURN QUERY
SELECT id_photo, id_user, lien, titre
FROM photo p
WHERE id_user IN (SELECT id_userabo
FROM abo
WHERE id_user = id )
ORDER BY date_publi DESC
LIMIT 10;
END;$$
LANGUAGE plpgsql;
I'm using Postgresql and trying to have a select statement in a function to call out. At the moment the call gives me zero results
CREATE OR REPLACE FUNCTION f_all_male_borrowers
(
OUT p_given_names varchar(60),
OUT p_family_name varchar(60),
OUT p_gender_code integer
)
RETURNS SETOF record as $body$
declare body text;
BEGIN
SELECT into p_given_names,p_family_name, p_gender_code
borrower.given_names, borrower.family_name, gender.gender_code
FROM BORROWER
INNER join gender on borrower.gender_code=gender.gender_code
WHERE borrower.gender_code = '1';
RETURN ;
END;
$body$ LANGUAGE plpgsql;
Call to function:
select * from f_all_male_borrowers()
What is missing, or what am I doing wrong here?
Thank you
CREATE OR REPLACE FUNCTION f_all_male_borrowers
(
OUT p_given_names varchar(60),
OUT p_family_name varchar(60),
OUT p_gender_code integer
)
RETURNS SETOF record as
$body$
SELECT into p_given_names,p_family_name, p_gender_code
borrower.given_names, borrower.family_name, gender.gender_code
FROM BORROWER
INNER join gender on borrower.gender_code=gender.gender_code
WHERE borrower.gender_code = '1';
$body$
LANGUAGE sql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION f_all_male_borrowers()
OWNER TO postgres;
Try this and then call :
select * from f_all_male_borrowers();
Before doing that you need to check whether your query have result or not !!
After creating function then:
Got to Functions->Right click your function(ie,f_all_male_borrowers())-> Scripts->Select Script ->Then run it.
If it returns result then your procedure is correct.