如何将表名传递给plpgsql函数

时间:2016-02-25 20:26:40

标签: postgresql function variables plpgsql dynamic-sql

我正在尝试运行代码:

CREATE OR REPLACE FUNCTION anly_work_tbls.testfncjh (tablename text) returns int
AS $$
DECLARE 
        counter int;
        rec record;
        tname text;
BEGIN
counter = 0;
tname := tablename; 
FOR rec IN
        select *
        from tname
    loop
        counter = counter + 1;
    end loop;
RETURN counter;
END; 
$$ 
LANGUAGE 'plpgsql' IMMUTABLE
SECURITY DEFINER;

此代码的目标是返回您输入的表中的行数。我知道这可能不是完成这项任务的最佳方法,但是这个函数的结构可以很好地扩展到我试图解决的另一个问题。每次运行代码时,都会收到错误:

  ERROR: syntax error at or near "$1"

我找到的所有在线资源都告诉我如何在EXECUTE块内使用输入变量,但不是在上述情况下。

目前正在运行PostgreSQL 8.2.15。

2 个答案:

答案 0 :(得分:1)

CREATE OR REPLACE FUNCTION anly_work_tbls.testfncjh (tbl regclass, OUT row_ct int) AS
$func$
BEGIN    
   EXECUTE 'SELECT count(*) FROM '|| tbl
   INTO row_ct;
END
$func$ LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER;

呼叫:

SELECT anly_work_tbls.testfncjh('anly_work_tbls.text_tbl');

这应该适用于Postgres 8.2,但无论如何你都是consider upgrading to a current version

如果您确实需要遍历动态查询的结果:

CREATE OR REPLACE FUNCTION anly_work_tbls.testfncjh (tbl regclass)
  RETURNS int AS
$func$
DECLARE 
   counter int := 0;  -- init at declaration time
   rec record;
BEGIN
   FOR rec IN EXECUTE
      'SELECT * FROM ' || tbl
   LOOP
      counter := counter + 1;  -- placeholder for some serious action
   END LOOP;

   RETURN counter;
END
$func$  LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER;

答案 1 :(得分:0)

是的,这不是最好的方式,但这可行:

CREATE OR REPLACE FUNCTION testfncjh (tablename text) returns int
AS $$
DECLARE 
        counter int;
        rec record;        
BEGIN
counter = 0;
FOR rec IN
        EXECUTE 'select * from '||quote_ident(tablename) loop
        counter = counter + 1;
    end loop;
RETURN counter;
END; 
$$ 
LANGUAGE 'plpgsql' IMMUTABLE
SECURITY DEFINER;

这会更好:

CREATE OR REPLACE FUNCTION testfncjh (tablename text) returns int
AS $$
DECLARE _count INT;
BEGIN    
 EXECUTE 'SELECT count(*) FROM '|| quote_ident(tablename) INTO _count;
 RETURN _count;
END; 
$$ 
LANGUAGE 'plpgsql' IMMUTABLE
SECURITY DEFINER;