微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

postgresql – 如何在plpgsql中将变量用作表名

我是plpgsql的新手.我正在尝试使用plpgsql中的变量作为表名在plpgsql中运行一个简单的查询.但是变量被解释为表名而不是被解释为变量名的变量的值.

DECLARE
  v_table text;
  z_table text;
  max_id bigint;

BEGIN

FOR v_table IN
    SELECT table_name  
    FROM @R_363_4045@ion_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;

一些背景资料.对于我的数据库中的每个表,我有一个以“z_”开头的表.例如.对于一个名为“employee”的表,我有一个名为“z_employee”的相同表. z_employee包含与employee相同的数据集.我在每次测试开始时使用它来恢复employee表.

当我运行此函数时,我收到以下错误

ERROR:  relation "z_table" does not exist
LINE 1: SELECT max(id) from z_table

我的猜测是我不允许在SQL查询中使用变量z_table.至少不是我在这里使用它的方式.但我不知道它应该如何完成.

解决方法

使用 dynamic SQL with EXECUTE,正确简化和转义标识符:

CREATE OR REPLACE FUNCTION f_test()
  RETURNS void AS
$func$
DECLARE
   v_table text;
BEGIN
   FOR v_table IN
      SELECT table_name  
      FROM   @R_363_4045@ion_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;

请注意,可能需要引用表名称,或者引入语法错误甚至sql注入!我使用方便的format()来正确连接DELETE语句和转义标识符.

>单独的SELECT会更贵.您可以使用单个DELETE语句完成所有操作.

有关:

> Table name as a PostgreSQL function parameter
> How to check if a table exists in a given schema

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐