Return data from Common Table Expression in postgres - postgresql

I am trying to return some data I have from Common Table Expression to my backend but unable to because Postgres doesn't see the table.
CREATE OR REPLACE FUNCTION request(
question_id_func INTEGER,
requester_account_id_func INTEGER,
counter_func NUMERIC
) RETURNS INTEGER AS $$
with notif AS (
INSET INTO notification(...) VALUES (...) RETURNING *
)
UPDATE question....
RETURN (SELECT notif_id FROM notif);
END $$ LANGUAGE PLPGSQL
Does anyone has a better idea how you can extract the data from CTE and return it?
Much appreciated.

You will need to put your UPDATE statement into a CTE, and then assign the output to a function variable using a final SELECT statement.
For example:
CREATE OR REPLACE FUNCTION request(
question_id_func INTEGER,
requester_account_id_func INTEGER,
counter_func NUMERIC
) RETURNS INTEGER AS $body$
DECLARE
result integer;
BEGIN
WITH notif AS (
INSERT INTO notification(...) VALUES (...) RETURNING *
),
question_update AS (
UPDATE question....
)
SELECT notif.notif_id INTO result FROM notif;
RETURN result;
END $body$ LANGUAGE PLPGSQL

Related

Query returned successfully but i dont see anyway

I'm new to postgresql, i have a procedure block this is working but i dont see any table or column, what this problem.
CREATE PROCEDURE list3(
)
LANGUAGE sql
AS $$
select * from stok
$$;
call list3()
Functions return values.
Example:
create table table_example(col1 varchar(100),col2 int);
CREATE OR REPLACE FUNCTION get_table_example()
RETURNS TABLE (
l_col1 VARCHAR,
l_col2 INT
)
LANGUAGE plpgsql
AS $$
BEGIN
RETURN QUERY
SELECT *
FROM table_example;
END;
$$
select * from get_table_example();

Error while creating table : Syntax error at or near "#"

I am trying to convert SQL Server stored function to PostgreSQL stored function I am getting one syntactical error at declare #table1 table
CREATE OR REPLACE FUNCTION ETL_GetBuildingDetailsByUserID ( p_nInstID numeric=0)
RETURNS Boolean
AS $$
declare #table1 table
(
nbuilding numeric(18, 0) NOT NULL,
sbuild_name varchar(50) NULL,
sclient_build_id varchar(50) NULL,
nbuilding_inst_id numeric(18, 0) NOT NULL,
ntemp_building_id numeric(18,0) NULL,
nno_of_floors numeric(18,0) NULL
)
declare v_strDeptIds text;
v_strSubDeptIds text;
BEGIN
v_strsql := 'SELECT building.*
FROM building
WHERE (building.nbuilding_inst_id = '|| cast(p_nInstID as varchar(1)) ||')
';
print v_strsql
v_strsql1 text;
v_strsql1 := v_strsql
Insert into #table1; execute sp_executesql; v_strsql1
select * from #table1;
Return true;
END;
$$ LANGUAGE plpgsql;
Error
ERROR: syntax error at or near "#"
LINE 4: declare #table1 table
Can any one please tell what I am doing wrong?
It seems your function actually returns the result of a SELECT query, not a boolean value, so returns boolean is wrong to begin with.
To return a result, you need to declare the function as returns table(). But as you seem to simply return rows from the building table you can define it as returns setof building.
Then remove the useless dynamic SQL which seems completely unnecessary.
In PL/pgSQL there are no table variables, and copying the result of a query into one before returning that result from that table seems to be an unnecessary step which only slows down things. In Postgres you simply return the result of the query, there is no need to store it locally.
Additionally: rather than casting a parameter to another type inside the function it's better to declare that parameter with the type you expect.
So the simplified version of that function in PostgreSQL would be:
CREATE OR REPLACE FUNCTION ETL_GetBuildingDetailsByUserID ( p_nInstID text)
RETURNS setof building
AS $$
select building.*
from building
WHERE building.nbuilding_inst_id = p_nInstID
$$ LANGUAGE sql;
You can use it like this:
select *
from ETL_GetBuildingDetailsByUserID ('42');
Unrelated, but: using numeric(18,0) for columns that store values without decimals is overkill. You should define those columns as bigint. Much faster and uses less space than numeric.

In clause in postgres

Need Output from table with in clause in PostgreSQL
I tried to make loop or ids passed from my code. I did same to update the rows dynamically, but for select I m not getting values from DB
CREATE OR REPLACE FUNCTION dashboard.rspgetpendingdispatchbyaccountgroupidandbranchid(
IN accountgroupIdCol numeric(8,0),
IN branchidcol character varying
)
RETURNS void
AS
$$
DECLARE
ArrayText text[];
i int;
BEGIN
select string_to_array(branchidcol, ',') into ArrayText;
i := 1;
loop
if i > array_upper(ArrayText, 1) then
exit;
else
SELECT
pd.branchid,pd.totallr,pd.totalarticle,pd.totalweight,
pd.totalamount
FROM dashboard.pendingdispatch AS pd
WHERE
pd.accountgroupid = accountgroupIdCol AND pd.branchid IN(ArrayText[i]::numeric);
i := i + 1;
end if;
END LOOP;
END;
$$ LANGUAGE 'plpgsql' VOLATILE;
There is no need for a loop (or PL/pgSQL actually)
You can use the array directly in the query, e.g.:
where pd.branchid = any (string_to_array(branchidcol, ','));
But your function does not return anything, so obviously you won't get a result.
If you want to return the result of that SELECT query, you need to define the function as returns table (...) and then use return query - or even better make it a SQL function:
CREATE OR REPLACE FUNCTION dashboard.rspgetpendingdispatchbyaccountgroupidandbranchid(
IN accountgroupIdCol numeric(8,0),
IN branchidcol character varying )
RETURNS table(branchid integer, totallr integer, totalarticle integer, totalweight numeric, totalamount integer)
AS
$$
SELECT pd.branchid,pd.totallr,pd.totalarticle,pd.totalweight, pd.totalamount
FROM dashboard.pendingdispatch AS pd
WHERE pd.accountgroupid = accountgroupIdCol
AND pd.branchid = any (string_to_array(branchidcol, ',')::numeric[]);
$$
LANGUAGE sql
VOLATILE;
Note that I guessed the data types for the columns of the query based on their names. You have to adjust the line with returns table (...) to match the data types of the select columns.

PSQLException: ERROR: syntax error at or near "test"

I'm getting the same error as in the title:
CREATE OR REPLACE FUNCTION func(param varchar) RETURNS varchar AS
'BEGIN
LOCK public.routes;
return (SELECT * FROM public.routes WHERE guid = 'test');
END;' LANGUAGE plpgsql
What might be the problem? I can execute the same in console and it's gonna work.
You need to escape single quotes embedded in string literals by doubling them:
CREATE OR REPLACE FUNCTION func(param varchar) RETURNS varchar AS
'BEGIN
LOCK public.routes;
return (SELECT * FROM public.routes WHERE guid = ''test'');
END;' LANGUAGE plpgsql
That's the reason why people usually use dollar quoting for the body of functions:
CREATE OR REPLACE FUNCTION func(param varchar) RETURNS varchar AS
$body$
BEGIN
LOCK public.routes;
return (SELECT * FROM public.routes WHERE guid = 'test');
END;
$body$
LANGUAGE plpgsql
However, even if you get the syntax right: the function will not work. It is defined to return a single (scalar) value of type varchar but it returns the all rows from the table routes. If you want to return multiple rows, you need to define the function as returns setof or returns table. In your case returns setof routes would be applicable:
CREATE OR REPLACE FUNCTION func(param varchar)
RETURNS setof public.routes
AS
$body$
BEGIN
LOCK public.routes;
return (SELECT * FROM public.routes WHERE guid = 'test');
END;
$body$
LANGUAGE plpgsql
If you intend to return the value of a single column of a single row (assuming that guid is defined as PK or unique), then indeed returns varchar would work. But then you should change the select statement to select some_column from .. or something similar

Select statement within function blank results

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.