Ste*_*ven 6 postgresql dynamic-sql plpgsql
我是plpgsql的新手.我正在尝试使用plpgsql中的变量作为表名在plpgsql中运行一个简单的查询.但是变量被解释为表名而不是被解释为变量名的变量的值.
DECLARE
v_table text;
z_table text;
max_id bigint;
BEGIN
FOR v_table IN
SELECT table_name
FROM information_schema.tables
WHERE table_catalog = 'my_database'
AND table_schema = 'public'
AND table_name not like 'z_%'
LOOP
z_table := 'z_' || v_table;
SELECT max(id) from z_table INTO max_id;
DELETE FROM v_table where id > max_id;
END LOOP;
Run Code Online (Sandbox Code Playgroud)
一些背景资料.对于我的数据库中的每个表,我有另一个以"z_"开头的表.例如,对于一个名为"employee"的表,我有一个名为"z_employee"的相同表.z_employee包含与员工相同的数据集.我在每次测试开始时使用它来恢复employee表.
当我运行此函数时,我收到以下错误:
ERROR: relation "z_table" does not exist
LINE 1: SELECT max(id) from z_table
Run Code Online (Sandbox Code Playgroud)
我的猜测是我不允许z_table在SQL查询中使用该变量.至少不是我在这里使用它的方式.但我不知道它应该如何完成.
Erw*_*ter 12
正确使用动态SQLEXECUTE,简化和转义标识符:
CREATE OR REPLACE FUNCTION f_test()
RETURNS void AS
$func$
DECLARE
v_table text;
BEGIN
FOR v_table IN
SELECT table_name
FROM information_schema.tables
WHERE table_catalog = 'my_database'
AND table_schema = 'public'
AND table_name NOT LIKE 'z_%'
LOOP
EXECUTE format('DELETE FROM %I v WHERE v.id > (SELECT max(id) FROM %I)'
, v_table, 'z_' || v_table);
END LOOP;
END
$func$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
请注意,可能需要引用表名称,或者引入语法错误甚至SQL注入!我使用方便的方法format()来DELETE正确地连接语句和转义标识符.
SELECT会更贵.您可以使用单个DELETE语句完成所有操作.有关:
| 归档时间: |
|
| 查看次数: |
10225 次 |
| 最近记录: |