CREATE OR REPLACE FUNCTION getParentLtree(parent_id bigint, tbl_name varchar)
RETURNS ltree AS
$BODY$
DECLARE
parent_ltree ltree;
BEGIN
-- This works fine:
-- select into parent_ltree l_tree from tbl1 where id = parent_id;
EXECUTE format('select into parent_ltree l_tree from %I
where id = %I', tbl_name,parent_id);
RETURN parent_ltree;
END;
$BODY$ LANGUAGE plpgsql;
There are 2 issues in above function:
parent_id
isinteger
but it is replaced with quotes? What is the correct format specifier forint
variables?select into
does not work withEXECUTE
? How can I make above commented query to use table name passed?
Use
%s
for strings.%I
is for identifiers:http://www.postgresql.org/docs/current/static/functions-string.html#FUNCTIONS-STRING-FORMAT
PL/pgSQL's
select into
is not the same as Postgresql'sselect into
. Use insteadcreate table as
:http://www.postgresql.org/docs/current/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW
To
select into
a variable from anexecute
statement:http://www.postgresql.org/docs/current/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN
This would be shorter, faster and safer:
Why?
Most importantly, use the
USING
clause ofEXECUTE
for parameter values. Don't convert them totext
, concatenate and interpret them back. That would be slower and error-prone.Normally you would use the
%I
specifier withformat()
for identifiers like the table name. There is an even better way, though: use aregclass
object-identifier type. Details here:Table name as a PostgreSQL function parameter
Use an
OUT
parameter to simplify your code. Performance is the same.Don't use unquoted CaMeL case identifiers like
getParentLtree
in Postgres. Details in the manual.