Postgresql

在 Postgres 觸發器中按鍵分配給 NEW

  • March 20, 2021

在觸發器正文中,如何NEW通過欄位名稱為其賦值?

這就是我想要做的:

some_key = "some_column";
NEW[some_key] = 5;

首先,沒有“觸發器體”(與 Oracle 不同)。在 Postgres 中,您有一個觸發器函式(也有誤導性地稱為“過程”),它有一個函式體和呼叫此函式的 0-n 個觸發器(沒有函式體)。

plpgsql 觸發函式中的特殊變數NEW既不是映射也不是數組;這是保持新行的記錄:

NEW

數據類型RECORD;為行級觸發器中的INSERT/操作保存新數據庫行的變數 。UPDATE此變數在語句級觸發器和DELETE操作中未分配。

分配給一個欄位(或列)NEW很簡單。記錄的賦值運算符是:=. (從 Postgres 9.4 開始也是=

NEW.some_key := 5;

您似乎正在尋找的是參數化列 name,這並不那麼簡單。附加模組提供操作

。(它幾乎包含在所有標準發行版中。)每個數據庫安裝一次模組:hstore#=

CREATE EXTENSION hstore;

那麼你就可以:

NEW := NEW #= '"some_key"=>"5"'::hstore;

將列設置some_key為 ‘5’ - 如果該列存在。

  • 顯式轉換hstore為可選。運算符#=自動將字元串文字強制轉換為正確的數據類型。
  • hstore僅儲存文本字元串,因此值的給定文字可能必須轉換兩次- 與替代解決方案相比,這是一個非常小的缺點。
  • 給定的字元串文字必須適合列的數據類型,否則會引發異常。
  • 如果不存在具有給定名稱的列,則不會更改任何內容,不會引發異常。

詳細資訊和替代解決方案的相關答案:

程式碼範例

CREATE OR REPLACE FUNCTION trg_tbl_ins_bef()
 RETURNS trigger AS
$func$
BEGIN
  NEW := NEW #= '"some_key"=>"5"';
  RETURN NEW;
END
$func$ LANGUAGE plpgsql;

CREATE TRIGGER ins_bef
BEFORE INSERT ON tbl
FOR EACH ROW EXECUTE PROCEDURE trg_tbl_ins_bef();

Postgres 11 或更高版本允許替換誤導性術語PROCEDURE(舊語法將在可預見的未來繼續工作):

...
FOR EACH ROW EXECUTE FUNCTION trg_tbl_ins_bef();

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