I’m Newbie in postgres. I wrote a function, which insert into table a data by portions(because there is too much data in the source table to do it all at once) from another table:
CREATE OR REPLACE FUNCTION data_load(p_src_schema character varying, p_src_tab character varying,p_tgt_schema character varying, p_tgt_tab character varying)
RETURNS void AS
$BODY$
DECLARE
table_rec record;
BEGIN
FOR table_rec IN
SELECT otchdor, descr
FROM otchdor
ORDER BY otchdor
loop
insert into p_tgt_schema||'.'||p_tgt_tab
select from p_src_schema||'.'||p_src_tab
where otchdor = table_rec.otchdor;
end loop;
return;
END;
$BODY$
LANGUAGE plpgsql
;
got SQL Error [42601]: ERROR: syntax error at or near "||"
How correctly concat schema and table names at query?
Where did I go wrong?
use:
PostgreSQL 9.4.24 (Greenplum Database 6.14.0 build commit:Open Source) on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 6.4.0, 64-bit
2
Answers
For that you need dynamic sql
fiddle
Assuming Greenplum copied Postgres 9.4 functionality for PL/pgSQL functions. I don’t actually use Greenplum.
Use dynamic SQL with
EXECUTE
. Best withformat()
to concatenate the query string comfortably and safely:The format specifier
%I
is for identifiers and correlates toquote_ident()
. Either double-quotes identifiers safely as needed, to defend against SQL injection and syntax errors.quote_nullable()
(like has been suggested) would be nonsense for identifiers. Also, best pass the value as (typed) value with theUSING
clause See:Also, the DDL command would fail if any identifier was
null
, so I made the functionSTRICT
. The manual:But I don’t think this function makes much sense to begin with. Chopping up that big
INSERT
would make sense with separate transactions (like you could employ in aPROCEDURE
in modern Postgres, but not in Greenplum). A function always runs inside a single transaction anyway.