Reputation: 89
Following is my function
created in PostgreSQL 9.2
CREATE OR REPLACE function fn_exp_settl_cr
(branchid int
,vrid int
,ddate date
,acid int
)
returns
TABLE ( trno character varying(15), trdate timestamp without time zone, netamt money, duedate
timestamp without time zone,tranid integer, acyrid integer, custrefno
charactervarying(26), orderdate timestamp without time zone) as $$
declare
sql text;
begin
execute 'select string_agg(s.qry,'' UNION ALL '') from (select ''SELECT
TrNo,TrDate,NetAmt,DueDate,TranId,AcYrId,custrefno,orderdate FROM '||t.relname||' WHERE
AdjInBill = false And ExpSettled = false And (BranchID = 1) AND (VrId = 29) and
DueDate <= ''2014-07-24'' and AcId=76 '' qry from (select relname from
pg_stat_user_tables where relname ilike ''gtab09%'') t )s ' into sql;
execute sql;
end;
$$ language plpgsql
It creates successfully but when calling this function, i.e.:
select * from fn_exp_settl_cr(1,2,'2014-07-24',4)
I get the following error:
ERROR: missing FROM-clause entry for table "t" LINE 1: ...DueDate,TranId,AcYrId,custrefno,orderdate FROM '||t.relname|...
Upvotes: 0
Views: 107
Reputation: 656411
CREATE OR REPLACE function fn_exp_settl_cr(_branchid int, _vrid int
, _ddate date, _acid int)
RETURNS TABLE (
trno character varying(15)
, trdate timestamp
, netamt money
, duedate timestamp
, tranid integer
, acyrid integer
, custrefno character varying(26)
, orderdate timestamp
) AS
$func$
BEGIN
RETURN QUERY EXECUTE (
SELECT string_agg
(format
($$SELECT TrNo,TrDate,NetAmt,DueDate,TranId,AcYrId
,custrefno,orderdate
FROM %I
WHERE AdjInBill = false
AND ExpSettled = false
AND BranchID = $1
AND VrId = $2
AND DueDate <= $3
AND AcId = $4
$$
,t.relname
)
,' UNION ALL '
)
FROM pg_class t
WHERE t.relkind = 'r' -- ordinary table
AND t.relname ILIKE 'gtab09%'
)
USING _branchid, _vrid, _ddate, _acid;
END
$func$ LANGUAGE plpgsql;
Your format is hardly readable, which is probably the main reason you can't find the problem.
Typo in charactervarying(26)
. Fix: character varying(26)
. I would just use varchar
or text
, though.
You got confused with multiple layers of quoting. The fix is to use dollar-quoting and format()
to build your string. Also, one or two layers can just be simplified away.
You are not actually using your input parameters. Probably because you got stuck and are testing with literal values. While being at it, I built those in, too, with a USING
clause.
I suggest not to use the same identifiers as parameter names. Those are visible in the function body everywhere and easily lead to naming conflicts. Prepended with '_'.
You didn't actually return anything. Use RETURN QUERY EXECUTE
instead of just EXECUTE
for that end.
And why retrieve table names from the statistics view pg_stat_user_tables
? It's cheaper and more reliable to get it from the information schema or the catalog table pg_class
. Changed that, too.
Upvotes: 2