Db2

DB2 更新觸發器

  • December 5, 2014

我正在嘗試在DB2數據庫中創建一個觸發器,該觸發器在更新一個表中的列時執行,然後用某些值填充另一個表。

例如,有一個帶有一FLEET_ID列的功率單位表。每次FLEET_ID更改時,我都需要在TRANS_AUDIT表中創建一個新行。

TRANS_AUDIT架構如下:

CREATE TABLE LYNX.TRANS_AUDIT (
TA_ID INTEGER NOT NULL,
TA_KEY_VALUE VARCHAR(100),
TA_TABLE_CHANGED VARCHAR(40),
TA_FIELD_CHANGED VARCHAR(40),
TA_OLD_FIELD_VALUE VARCHAR(100),
TA_NEW_FIELD_VALUE VARCHAR(100),
TA_USER_WHO_CHANGED VARCHAR(128),
TA_DATE_CHANGED TIMESTAMP,
TA_COMMENT VARCHAR(40),
TA_OLD_FIELD_DOUBLE DOUBLE DEFAULT 0,
TA_NEW_FIELD_DOUBLE DOUBLE DEFAULT 0,
PRIMARY KEY (TA_ID)
);

這是我到目前為止所擁有的,但我似乎無法讓它工作,我收到“函式序列”錯誤。

CREATE TRIGGER PU_UPD_FLEETID
 AFTER UPDATE OF FLEET_ID ON PUNIT 
 REFERENCING OLD AS O NEW AS N
 FOR EACH ROW 
 MODE DB2SQL 

 BEGIN ATOMIC 

 DECLARE 
   vTA_ID INTEGER;

 IF(N.FLEET_ID <> O.FLEET_ID) THEN

   SELECT MAX(TA_ID)+1 INTO vTA_ID; --generate a unique sequential id

   INSERT INTO LYNX.TRANS_AUDIT
   (TA_ID, TA_KEY_VALUE, TA_TABLE_CHANGED, TA_FIELD_CHANGED, TA_OLD_FIELD_VALUE, 
   TA_NEW_FIELD_VALUE, TA_USER_WHO_CHANGED, TA_DATE_CHANGED, TA_COMMENT, 
   TA_OLD_FIELD_DOUBLE, TA_NEW_FIELD_DOUBLE)
   VALUES 
   (TA_ID, N.UNIT_ID , 'PUNIT', 'FLEET_ID', O.FLEET_ID, N.FLEET_ID , SESSION_USER 
   ,CURRENT TIMESTAMP , '', '0' ,'0' );
 END IF;
END;

我在您的觸發器中註意到,您的程式碼說:

   INSERT INTO LYNX.TRANS_AUDIT
       (TA_ID, TA_KEY_VALUE, TA_TABLE_CHANGED, TA_FIELD_CHANGED, ...)
     VALUES 
       (TA_ID, N.UNIT_ID , 'PUNIT', 'FLEET_ID',  ...);

但是VALUES子句不應該包含vTA_ID嗎?

   INSERT INTO LYNX.TRANS_AUDIT
       (TA_ID, TA_KEY_VALUE, TA_TABLE_CHANGED, TA_FIELD_CHANGED, ...)
     VALUES 
       (vTA_ID, N.UNIT_ID , 'PUNIT', 'FLEET_ID', ...);

但是,使用您的查詢計算 vTA_ID 可能不是您最有效的選擇。

您可以創建一個 SEQUENCE 對象,並讓它始終計算新值。

   CREATE SEQUENCE TRANS_AUDIT_SEQ AS INTEGER;

然後在你的觸發器中,

   INSERT INTO LYNX.TRANS_AUDIT
       (TA_ID, TA_KEY_VALUE, TA_TABLE_CHANGED, TA_FIELD_CHANGED, ...)
     VALUES 
       (NEXT VALUE FOR TRANS_AUDIT_SEQ, N.UNIT_ID , 'PUNIT', 'FLEET_ID', ...);

但是最適合您的可能是將您的 ID 列定義為 IDENTITY

CREATE TABLE LYNX.TRANS_AUDIT (
TA_ID INTEGER  GENERATED BY DEFAULT AS IDENTITY,
   ...
PRIMARY KEY (TA_ID)
);

然後在您的觸發器中,您不需要指定該值,因為它將為您生成:

   INSERT INTO LYNX.TRANS_AUDIT
       (TA_KEY_VALUE, TA_TABLE_CHANGED, TA_FIELD_CHANGED, ...)
     VALUES 
       (N.UNIT_ID , 'PUNIT', 'FLEET_ID',  ...);

除非有其他未提及的因素,否則這很可能是 3 種解決方案中最適合您的。

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