Trigger

獲取目前表名觸發器被觸發

  • January 4, 2021

我的系統:Linux 上的 Db2 11.1。

1.創建一些表:

create table admin.tab (a int not null primary key, b int) @

2.創建審計表:

create table admin.audit (table_name varchar(2000), datetime timestamp) @

3.非常簡單的範例,當插入源表 admin.tab 時,我想插入到 admin.audit:

create trigger admin.mytrig
after insert on admin.tab
referencing new as new
for each row
begin
   insert into admin.audit (table_name, datetime) 
      values ('admin.tab', current_timestamp);
end
@

4.上面的觸發器工作正常,但是上面的觸發器有什麼辦法我可以用使用觸發器觸發的目前表名替換’admin.tab’常量,比如CURRENT_TABLE_TRIGGER_WAS_FIRED_ON什麼?

create trigger admin.mytrig
after insert on admin.tab
referencing new as new
for each row
begin
   insert into admin.audit (table_name, datetime) 
      values (CURRENT_TABLE_TRIGGER_WAS_FIRED_ON, current_timestamp);
end
@

我需要這種解決方案,因為我需要創建數百個這樣的觸發器並儘可能多地共享程式碼可以節省大量時間。

有什麼方法可以在觸發器內部獲取定義觸發器的表的名稱?

不,在任何目前(截至 2020 年)Db2 版本中都沒有這樣的功能,原因我不會詳細介紹。為了進行比較,請考慮為什麼 C 函式不知道它的名稱或呼叫它的函式的名稱。

對於您編寫的每個觸發器,您必須在編寫時知道相應的表名,因為它是觸發器定義的一部分:

CREATE TRIGGER <name> ... ON <table name>

並且將該名稱作為文字添加到INSERT語句中也很簡單。

如果您面臨創建大量幾乎相同觸發器的繁瑣任務,請使用您最喜歡的腳本語言和可用的模板引擎之一來定義觸發器模板並從中為您的所有觸發器生成 DDL 語句。

或者,考慮使用Db2 審計工具,它完全能夠執行您的觸發器應該執行的操作。

使用這樣的 DB2 SQL 複合語句程式碼生成所需的觸發器會更好地為您服務

BEGIN
   FOR C AS cur CURSOR WITH HOLD FOR
       SELECT        'CREATE TRIGGER "'  || RTRIM(TABSCHEMA) || '"."' || TABNAME || '_TRIG"'
       || CHR(10) || 'AFTER INSERT ON "' || RTRIM(TABSCHEMA) || '"."' || TABNAME || '"'
       || CHR(10) || 'REFERENCING NEW AS NEW FOR EACH ROW'
       || CHR(10) || 'INSERT INTO ADMIN.AUDIT VALUES (''' || TABSCHEMA || ''',''' || TABNAME || ''', CURRENT_TIMESTAMP )'
           AS STMT
       FROM
           SYSCAT.TABLES
       WHERE
           TABSCHEMA = 'PAUL'
       AND TYPE      = 'T'
       AND TABLEORG  = 'R'
       AND (TABSCHEMA, TABNAME || '_TRIG') NOT IN (SELECT TRIGSCHEMA, TRIGNAME FROM SYSCAT.TRIGGERS)
       ORDER BY 
           TABSCHEMA
       ,   TABNAME
   DO
         EXECUTE IMMEDIATE C.STMT;
   END FOR;
END

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