【问题标题】:Capturing insert, update and delete events on a table Trigger's and insert into another table捕获表上的插入、更新和删除事件触发器并插入到另一个表中
【发布时间】:2016-07-17 07:46:18
【问题描述】:

我有一个跟踪整个系统/解决方案的活动表。 我在上面的 Activity 表上创建了一个触发器。通过这个触发器,我正在捕获系统的每个事件,这些事件将被其他系统使用。此外,我将更改(I/U/D)插入到 Event 和 EVENTCOLVAL 表中。 EVENTCOLVAL 表包含 Activity 表的所有列名和对应值。

所以我的触发器看起来像这样:

 CREATE OR REPLACE TRIGGER TRIG_Actv
    AFTER INSERT or UPDATE
       ON Activity
       FOR EACH ROW
    DECLARE
        lvEventId number;
    BEGIN
lvEventId := EventUniqId.NEXTVAL;
    INSERT ALL
          INTO Event (EventId,DateLastMaint)
          VALUES (lvEventId, SYSTIMESTAMP)
          INTO EVENTCOLVAL (EventId, COLNAME, COLVALUE)
          VALUES (lvEventId, 'ActivityCol1', :new.ActivityCol1)
          INTO EVENTCOLVAL (EventId, COLNAME, COLVALUE)
          VALUES (lvEventId, 'ActivityCol2', :new.ActivityCol2)
          INTO EVENTCOLVAL (EventId, COLNAME, COLVALUE)
          VALUES (lvEventId, 'ActivityCol3', :new.ActivityCol3)
          INTO EVENTCOLVAL (EventId, COLNAME, COLVALUE)
          VALUES (lvEventId, 'ActivityCol4', :new.ActivityCol4)
          INTO EVENTCOLVAL (EventId, COLNAME, COLVALUE)
          VALUES (lvEventId, 'ActivityCol5', :new.ActivityCol5)
          INTO EVENTCOLVAL (EventId, COLNAME, COLVALUE)
          VALUES (lvEventId, 'ActivityCol6', :new.ActivityCol6)
          INTO EVENTCOLVAL (EventId, COLNAME, COLVALUE)
          VALUES (lvEventId, 'ActivityCol7', :new.ActivityCol7)
          INTO EVENTCOLVAL (EventId, COLNAME, COLVALUE)
          VALUES (lvEventId, 'ActivityCol8', :new.ActivityCol8)
          ---
          ---
          ---
          ---
          --- 
          INTO EVENTCOLVAL (EventId, COLNAME, COLVALUE)
          VALUES (lvEventId, 'ActivityCol30', :new.ActivityCol30)
          SELECT * FROM dual;
EXCEPTION
  WHEN OTHERS THEN
    -------
END TRIG_Actv;

P.S:我不想在触发器中对表 EVENTCOLVAL 使用多次插入,因为这会影响性能,因为我在 Activity 表中有 30 列,插入 31 行将是性能问题。此外,活动表的指标是 1 秒内至少 100 次插入。因此,每秒插入至少 3000 行。由于触发器的同步特性,这将使活动屏幕变慢,实际上整个系统也变慢。有没有其他方法可以

【问题讨论】:

    标签: sql oracle performance plsql triggers


    【解决方案1】:

    您可以创建嵌套集合 + 使用复合触发器(例如 http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/triggers.htm#CIHEFGFD)+ forall 插入。 伪代码:

    CREATE OR REPLACE TRIGGER compound_trigger ...
    ........
    l_nested t_nested := t_nested();
    ........
    BEFORE EACH ROW IS
       BEGIN
        l_nested.extend();
        l_nested(l_nested.count) := ...//populate single row
    END BEFORE EACH ROW;
    
    AFTER STATEMENT IS
     BEGIN
        FORALL i IN 1..l_nested.count
         INSERT INTO EVENTCOLVAL(EventId, COLNAME, COLVALUE) VALUES (l_nested(i).eventId, l_nested(i).colName,l_nested(i).value);
     END AFTER STATEMENT;
    

    【讨论】:

    • 很抱歉这么晚才发表评论。我明白你说的集合,我也明白你说使用 FORALL 插入,但不明白你为什么说使用复合触发器。等待接受您的回答,顺便说一句,非常感谢您的回复:)
    • @AnkurBhutani 在行 stmt 之前的复合跳跳虎中,您将所有 stmt 添加到集合中。然后在 stmt 之后一次插入所有 stmt 。想象一下这个例子:你在一个 stmt 中更新 3 行。然后通常触发使 3 个单独的插入和复合识别它是一个 stmt。它在每行之前触发 3 次,收集数据并在 stmt 之后插入 3 条记录。
    • 听起来很有趣,我会试一试,谢谢。接受你的回答:)
    猜你喜欢
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 2011-05-05
    • 2020-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多