为了完整起见:另一种选择是有一个说法触发器,它扫描表,然后进行删除,如:
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;
或者,如果你真的希望有一些乐趣,你可以使用一个混合触发器来处理删除,而不需要一个表扫描,同时还避免了可怕的“变异表”的错误,如:
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;
分享和享受。
如果使用语句级触发器而不是行级触发器,则可以在触发器表上执行DML。 – 2012-04-17 17:46:10
当然可以。我已经更新了我的答案。感谢您指出错误。 – 2012-04-17 20:38:44