在PostgreSQL 9.1中,我需要将一个表名作为参数传递给我在函数中使用的函数 - 然后调用函数:
select myfunction('tableA');
或:
select myfunction('tableB')
我试过这个:
create or replace function myfunction(sid text)
returns integer as $BODY$
declare
bids cursor is select id from sid; --line 4
begin
for bid in bids loop
--some logic
end loop;
return 1;
end;
$BODY$
language plpgsql volatile;
我得到了error on line 4
。我明白了,它不允许将表名作为函数参数传递给它允许休息(选择,投影)。
是否有替代方案可以实现这一目标?
答案 0 :(得分:3)
只能在SQL命令中参数化值,而不能在标识符或关键字中参数化。它目前仅适用于SELECT
,INSERT
,UPDATE
和DELETE
命令。详细说明:
您需要在plpgsql中使用EXECUTE
的动态SQL
将它与FOR
循环的隐式游标相结合,这通常比显式游标更简单,更快。 Instructions in the manual.
我还建议使用regclass
参数安全地传递有效的表名。
CREATE OR REPLACE FUNCTION myfunction(_tbl regclass)
RETURNS int AS
$func$
DECLARE
bid integer; -- appropriate data type!
BEGIN
FOR bid IN EXECUTE
'SELECT id FROM ' || _tbl
LOOP
-- statements can use bid
RAISE NOTICE '%', bid;
END LOOP;
RETURN 1;
END
$func$ LANGUAGE plpgsql;
呼叫:
SELECT myfunction('tableA'); -- careful: case sensitive!
更多解释:
通常,有一个更快的基于集合的解决方案,根本不需要循环。
如果您肯定需要光标,请声明 未绑定光标 并使用OPEN FOR EXECUTE
打开它:
CREATE OR REPLACE FUNCTION myfunction(_tbl text) -- could be regclass again
RETURNS int AS
$func$
DECLARE
_bids refcursor;
_rec record;
BEGIN
OPEN _bids FOR EXECUTE 'SELECT id FROM ' || quote_ident(_tbl); -- text must be escaped
LOOP
FETCH NEXT FROM _bids INTO _rec;
EXIT WHEN _rec IS NULL;
-- some logic
RAISE NOTICE '%', _rec.id;
END LOOP;
RETURN 1;
END
$func$ LANGUAGE plpgsql;
同一个电话。这个密切相关的答案的更多细节: