Db2
DB2 更新觸發器
我正在嘗試在
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 種解決方案中最適合您的。