如何在Postgres的PL/pgSQL函数中编写动态SELECT INTO
查询?
假设我有一个名为tb_name
的变量,该变量从FOR
填充到information_schema.tables
循环中。现在,我有一个名为tc
的变量,它将获取每个表的行数。我想要以下内容:
FOR tb_name in select table_name from information_schema.tables where table_schema='some_schema' and table_name like '%1%'
LOOP
EXECUTE FORMAT('select count(*) into' || tc 'from' || tb_name);
END LOOP
在这种情况下,
tb_name
和tc
的数据类型应该是什么? 最佳答案
CREATE OR REPLACE FUNCTION myfunc(_tbl_pattern text, _schema text = 'public')
RETURNS void AS -- or whatever you want to return
$func$
DECLARE
_tb_name information_schema.tables.table_name%TYPE; -- currently varchar
_tc bigint; -- count() returns bigint
BEGIN
FOR _tb_name IN
SELECT table_name
FROM information_schema.tables
WHERE table_schema = _schema
AND table_name ~ _tbl_pattern -- see below!
LOOP
EXECUTE format('SELECT count(*) FROM %I.%I', _schema, _tb_name)
INTO _tc;
-- do something with _tc
END LOOP;
END
$func$ LANGUAGE plpgsql;
笔记
_
),以避免命名与表列的冲突。只是一个有用的约定。 _tc
应该是 bigint
,因为这是合计函数count()
返回的内容。 _tb_name
的数据类型是动态地从其父列派生的:information_schema.tables.table_name
%TYPE
。请参阅Copying Types in the manual一章。 information_schema.tables
中列出的表吗?有道理,但要注意含义。看:EXECUTE
的查询)返回到(行)变量的单个行或值的方式。单个列(如示例中的count
)会自动从行类型分解,因此我们可以直接将其分配给标量变量tc
,这与将整行分配给记录或行变量的方式相同。有关的:search_path
中可能还有其他同名的表,这将导致完全错误的结果(并且非常令人困惑!),而无需进行模式限定。鬼bug的 bug !或此模式根本不在search_path
中,这会使该函数立即引发异常。~
中的正则表达式运算符table_name ~ _tbl_pattern
代替了table_name LIKE ('%' || _tbl_pattern || '%')
,这更为简单。无论哪种方式,请注意pattern参数中的特殊字符!看:_schema text = 'public'
中为模式名称设置了默认值。只是为了方便起见,您可能想要也可能不想要。看:解决your comment:要传递值,请使用
USING
子句,例如:EXECUTE format('SELECT count(*) FROM %I.%I
WHERE some_column = $1', _schema, _tb_name,column_name)
USING user_def_variable;
有关的:
关于postgresql - PL/pgSQL函数中的动态SELECT INTO,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45998984/