Kar*_*hik 5 postgresql dynamic-sql plpgsql variable-assignment stored-functions
如何SELECT INTO在Postgres的PL / pgSQL函数内编写动态查询?
假设我有一个名为的变量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
Run Code Online (Sandbox Code Playgroud)
应该是什么数据类型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;
Run Code Online (Sandbox Code Playgroud)
我在所有参数和变量前都添加了下划线(_),以避免与表列发生命名冲突。只是一个有用的约定。
_tc应该是bigint,因为这是聚合函数count()返回的内容。
的数据类型_tb_name是从其父列动态得出的:information_schema.tables.table_name%TYPE。请参阅手册中的“ 复印类型 ”一章。
确定要只列出中的表information_schema.tables吗?有道理,但要注意含义。看到:
a_horse已经指出了该手册,而Andy提供了一个代码示例。这是将动态查询返回的单行或值分配给EXECUTE(行)变量的方式。甲单柱(如count在本例中)从行类型自动分解,所以我们可以分配给标量变量tc直接-以同样的方式,我们将一整行分配给一个记录或者行变量。有关:
对动态查询中的表名进行模式限定。当前可能存在其他同名的表search_path,这将导致完全错误的结果(并且非常令人困惑!),而没有模式限定。鬼bug的臭虫!或根本不存在该模式search_path,这会使函数立即引发异常。
始终 正确引用标识符以防止SQL注入和随机错误。模式和表必须用引号引起来单独!看到:
我用正则表达式运算符~的table_name ~ _tbl_pattern替代table_name LIKE ('%' || _tbl_pattern || '%'),这是简单的。无论哪种方式,请注意pattern参数中的特殊字符!看到:
我在函数调用中为模式名称设置了默认值:_schema text = 'public'。为了方便起见,您可能想要也可能不想要。看到:
解决您的评论:要传递值,请使用以下USING子句:
EXECUTE format('SELECT count(*) FROM %I.%I
WHERE some_column = $1', _schema, _tb_name,column_name)
USING user_def_variable;
Run Code Online (Sandbox Code Playgroud)
有关:
| 归档时间: |
|
| 查看次数: |
5155 次 |
| 最近记录: |