Postgresql

如何在函式中按順序對錶列表執行 ALTER TABLE

  • February 5, 2016

我有一個模式(稱為import),其中數據作為表導入,以及一個處理所有數據的函式。之後,我想將這些表移到另一個模式(稱為data_archive)中。現有功能效果很好,但我找不到更改架構的方法;這是我為此編寫的一個函式:

我的想法是根據 aselect在為此管理製作的表格上提供的標準創建表格列表,然後遍歷此列表並執行以下操作Alter table xxxx SET schema data_archive

CREATE OR REPLACE FUNCTION archive_datasets()
 RETURNS VOID AS
$BODY$
DECLARE
  table_rec  record;

BEGIN

  FOR table_rec IN
     SELECT t.table_name
     FROM information_schema.tables AS t
     WHERE table_schema = 'import'
     AND quote_ident(t.table_name) IN (
             SELECT "table_name"
             FROM data_sets 
             WHERE status IN ('Processed', 'Archived', 'Deleted')
             ) 

  LOOP
    ALTER TABLE quote_ident(table_rec.table_name) SET schema data_archived;
  END LOOP;

END;
$BODY$
 LANGUAGE plpgsql;

但我收到此錯誤消息:

ERROR:  syntax error at or near "("
LINE 28:  ALTER TABLE quote_ident(table_rec.table_name) SET schema ...

所以我的問題是如何將表的名稱傳遞給這個ALTER TABLE查詢?或者我做錯了什麼?

我使用 PostgreSQL 9.3。

問題是您不能像ALTER TABLE上面那樣在直接的 SQL 語句中使用參數作為對象名稱(表、列等)。

我在這裡使用“直接”作為“動態”的對立面——你需要的東西:

...
loop
   EXECUTE format($$ALTER TABLE %I SET SCHEMA TO data_archived$$, 
                  table_rec.table_name);
END loop;
...

備註

  • 在這裡,我在建構動態查詢時使用美元報價。例如,這允許我使用“正常”語法,而不是乘以單引號(本範例中不存在)。這樣,大多數編輯都會很好地突出顯示這些語句。
  • 如果需要,我還使用format()格式%I說明符來正確引用對象名稱。quote_ident()這種方法比使用串聯字元串常量和一些呼叫來建構查詢更具可讀性。它存在於 9.1 和更新版本中。
  • 我有一種感覺,您將類似的東西進行比較quote_ident('This_table') IN ('This_table'),這是不正確的。quote_ident()兩邊都使用- 或者更容易省略引用並比較字元串值。

引用自:https://dba.stackexchange.com/questions/114771