簡體   English   中英

如何在plpgsql中使用變量作為表名

[英]How to use variable as table name in 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;

一些背景資料。 對於我數據庫中的每個表,我都有另一個以“z_”開頭的表。 例如,對於一個名為“employee”的表,我有一個名為“z_employee”的相同表。 z_employee包含與員工相同的數據集。 我用它在每次測試開始時恢復員工表。

當我運行此函數時,出現以下錯誤:

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

我的猜測是我不允許在 SQL 查詢中使用變量z_table 至少不是我在這里使用它的方式。 但我不知道它應該如何完成。

使用帶有EXECUTE動態 SQL,正確地簡化和轉義標識符:

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;

可能需要引用表名以防止語法錯誤甚至 SQL 注入! 我使用方便的format()來連接DELETE語句並正確轉義標識符。

  • 單獨的SELECT會更貴。 您可以使用單個DELETE語句完成所有操作。

有關的:

在旁邊:

您可以使用(稍微快一點)系統目錄pg_tables代替:

      SELECT tablename
      FROM   pg_catalog.pg_tables
      WHERE  schemaname = 'public'
      AND    tablename NOT LIKE 'z_%'

看:

information_schema.tables中的table_catalog在這里沒有等效項。 無論如何,只有當前數據庫的表是可見的。 所以當連接到錯誤的數據庫時,上面的謂詞WHERE table_catalog = 'my_database'會產生一個空的結果集。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM