CREATE OR REPLACE FUNCTION demo(vsql text, vals text[])
RETURNS void AS
$BODY$
BEGIN
execute vsql using vals;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
select demo('select $1 || $2', ARRAY['Barrett', ' Gilmour'] );
ERROR: there is no parameter $2
LINE 1: select $1 || $2
错误是postgres无法理解必须将数组中的两项扩展到输入参数$ 1和$ 2。它将整个数组理解为$ 1的值
答案 0 :(得分:0)
如在问题https://dba.stackexchange.com/questions/83278/postgressql-dynamic-execute-with-argument-values-in-array中所讨论的,EXECUTE ... USING将把数组视为单个参数。
您可以尝试使用此技巧,该技巧可以编辑传递的SQL语句,使$ n变为$ 1 [n]
vsql := regexp_replace( vsql, '[$]([0-9]+)', '$1[\1]', 'g' );
将数组vals
视为单个参数,但是参数化的select可以将其索引以获取元素。
a_horse_with_no_name提到了另一个问题,即您的函数实际上未返回任何内容。如果要查看正在执行什么:
-- anyelement is a polymorphic pseudo-type
-- problem with returning 'setof record' is that select * from so_demov3() gives error
-- ERROR: a column definition list is required for functions returning "record"
drop function so_demov3(anyelement, text, text[]);
create function so_demov3(rec_type anyelement, p_sql text, p_vals text[]) returns setof anyelement as
$$
declare v_sql text;
begin
-- edit the executable SQL stmt so that $n -> $1[n]
v_sql := regexp_replace( p_sql, '[$]([0-9]+)', '$1[\1]', 'g' );
return query execute v_sql using p_vals;
end;
$$
language plpgsql volatile;
并这样称呼它:
select * from so_demov3(null::text, 'select $1 || $2', array['Barrett', 'Gilmour'] );