【问题标题】:Creating a trigger that deletes a row when an attribute becomes negative [oracle sql]?创建当属性变为负数时删除行的触发器[oracle sql]?
【发布时间】:2012-04-17 03:27:16
【问题描述】:

我想创建一个触发器,当其属性之一变为负数时将删除一行。到目前为止我有这个,但它似乎不是有效的 sql:

CREATE OR REPLACE TRIGGER ZERO_COPIES_TRIGGER
after
update of counter_attribute
on my_table
referencing new as new
for each row when(new.copies < 0)
begin
  delete from my_table where my_table.id = :new.id;
end;

【问题讨论】:

    标签: sql oracle triggers


    【解决方案1】:

    这是行不通的。您不能对由行级触发器操作的表执行 DML。您将收到“变异表”错误。

    要获得您想要的结果,最好的办法是有一个标志或指示列来标识该记录要删除。然后,有一个单独的作业或进程或任何实际执行删除的东西。

    【讨论】:

    • 如果使用语句级触发器而不是行级触发器,则可以对触发表进行 DML。
    • 是的,当然。我已经更新了我的答案。感谢您指出错误。
    【解决方案2】:

    为了完整起见:另一种选择是有一个语句触发器,它扫描表然后执行删除,如下所示:

    CREATE OR REPLACE TRIGGER ZERO_COPIES_TRIGGER
          AFTER UPDATE OF COUNTER_ATTRIBUTE ON MY_TABLE
    BEGIN
      FOR aROW IN (SELECT ID
                     FROM MY_TABLE
                     WHERE COPIES < 0)
      LOOP
        DELETE FROM MY_TABLE
          WHERE ID = aROW.ID;
      END LOOP;
    END ZERO_COPIES_TRIGGER;
    

    或者,如果您真的想找点乐子,可以使用复合触发器来处理删除,而不需要进行表扫描,同时仍然避免可怕的“MUTATING TABLE”错误,如在:

    CREATE OR REPLACE TRIGGER COMPOUND_ZERO_COPIES_TRIGGER
      FOR UPDATE OF COUNTER_ATTRIBUTE ON MY_TABLE
    COMPOUND TRIGGER
      TYPE NUMBER_TABLE IS TABLE OF NUMBER;
      tblDELETE_IDS  NUMBER_TABLE;
    
      BEFORE STATEMENT IS
      BEGIN
        tblDELETE_IDS := NUMBER_TABLE();
      END BEFORE STATEMENT;
    
      AFTER EACH ROW IS
      BEGIN
        IF :NEW.COPIES < 0 THEN
          tblDELETE_IDS.EXTEND;
          tblDELETE_IDS(tblDELETE_IDS.LAST) := :NEW.ID;
        END IF;
      END AFTER EACH ROW;
    
      AFTER STATEMENT IS
      BEGIN
        IF tblDELETE_IDS.COUNT > 0 THEN
          FOR I IN tblDELETE_IDS.FIRST..tblDELETE_IDS.LAST LOOP
            DELETE FROM MY_TABLE
              WHERE ID = tblDELETE_IDS(I);
          END LOOP;
        END IF;
      END AFTER STATEMENT;
    END COMPOUND_ZERO_COPIES_TRIGGER;
    

    分享和享受。

    【讨论】:

      猜你喜欢
      • 2012-08-19
      • 2015-06-05
      • 1970-01-01
      • 2017-06-26
      • 1970-01-01
      • 2013-03-06
      • 1970-01-01
      • 2012-04-22
      • 1970-01-01
      相关资源
      最近更新 更多