Thread: PL/pgSQL: dynamic tablename
I am building a set of functions to manage some trees. I would like to use a dynamic tablename. Something like: CREATE FUNCTION fn_test(varchar, integer, varchar, varchar) RETURNS INTEGER AS ' DECLARE beforenode INT4; newid INT4; BEGIN SELECT INTO beforenode lft FROM $4 WHERE ID = $2; More processing RETURN newid; END; ' LANGUAGE 'plpgsql'; Problem is that I always get an error about $4 being used incorrectly. If I hardcode the name of the table it works just fine. Does anybody have any suggestion on how to use a dynamic tablename passed as an attribute in a function? Jochem
Jochem van Dieten <jochemd@oli.tudelft.nl> writes: > Does anybody have any suggestion on how to use a dynamic tablename > passed as an attribute in a function? You need to use EXECUTE. See past discussions. regards, tom lane
Jochem, You will need to use EXECUTE [sql code] from within your function if your using dynamic sql. For reasons why + examples please see: http://developer.postgresql.org/docs/postgres/plpgsql-statements.html#PLPGSQ L-STATEMENTS-EXECUTING-DYN-QUERIES hih steve boyle ----- Original Message ----- From: "Jochem van Dieten" <jochemd@oli.tudelft.nl> To: <pgsql-general@postgresql.org> Sent: Sunday, January 20, 2002 9:08 PM Subject: [GENERAL] PL/pgSQL: dynamic tablename > I am building a set of functions to manage some trees. I would like to > use a dynamic tablename. Something like: > > CREATE FUNCTION fn_test(varchar, integer, varchar, varchar) RETURNS > INTEGER AS ' > DECLARE > beforenode INT4; > newid INT4; > BEGIN > SELECT INTO beforenode lft > FROM $4 > WHERE ID = $2; > > More processing > > RETURN newid; > END; > ' LANGUAGE 'plpgsql'; > > Problem is that I always get an error about $4 being used incorrectly. > If I hardcode the name of the table it works just fine. > > Does anybody have any suggestion on how to use a dynamic tablename > passed as an attribute in a function? > > Jochem > > > ---------------------------(end of broadcast)--------------------------- > TIP 5: Have you checked our extensive FAQ? > > http://www.postgresql.org/users-lounge/docs/faq.html >
Tom Lane wrote: > Jochem van Dieten <jochemd@oli.tudelft.nl> writes: > >> Does anybody have any suggestion on how to use a dynamic tablename >> passed as an attribute in a function? >> > > You need to use EXECUTE. See past discussions. For the record: A nested FOR ... IN EXECUTE got me there. CREATE FUNCTION fn_test(varchar, varchar, integer, varchar) RETURNS INTEGER AS ' DECLARE a_output VARCHAR(4000); b_output VARCHAR(4000); c_output VARCHAR(4000); d_output VARCHAR(4000); e_output VARCHAR(4000); oldfield VARCHAR(10); oldinfo RECORD; newinfo RECORD; BEGIN IF $2 = ''ADD'' THEN IF $4 = ''sibling'' THEN oldfield := ''lft''; ELSE oldfield := ''rgt''; END IF; a_output = ''SELECT '' || oldfield || '' AS beforeValue FROM '' || $1 || '' WHERE ID = '' || $3; FOR oldinfo IN EXECUTE a_output LOOP b_output = ''UPDATE '' || $1 || '' SET rgt = rgt + 2 WHERE rgt >= '' || oldinfo.beforeValue; c_output = ''UPDATE '' || $1 || '' SET lft = lft + 2 WHERE lft >= '' || oldinfo.beforeValue; d_output = ''INSERT INTO '' || $1 || '' (lft, rgt) VALUES ('' || oldinfo.beforeValue || '' - 2, '' || oldinfo.beforeValue || '' - 1)''; e_output = ''SELECT currval('''''' || $1 || ''_id_seq'''') AS newid''; EXECUTE b_output; EXECUTE c_output; EXECUTE d_output; FOR newinfo IN EXECUTE e_output LOOP RETURN newinfo.newid; END LOOP; END LOOP; RETURN 67; END IF; RETURN 0; END; ' LANGUAGE 'plpgsql'; Thanks, Jochem