Oracle之前插入所有触发器

Gáb*_*rga 2 oracle triggers insert

我想在插入更多行之前创建一个触发器.在插入新数据之前,我想删除id的早期版本.

例如:

CREATE OR REPLACE TRIGGER mytableTrigger
BEFORE INSERT ALL ON mytable
BEGIN
    DELETE FROM mytable WHERE column2 = fooId; --I want to get fooId in here.
END;

INSERT ALL
  INTO mytable (column1, column2, column3) VALUES (Seq.nextval(), fooId, 'val1.3')
  INTO mytable (column1, column2, column3) VALUES (Seq.nextval(), fooId, 'val2.3')
  INTO mytable (column1, column2, column3) VALUES (Seq.nextval(), fooId, 'val3.3')
SELECT * FROM dual;
Run Code Online (Sandbox Code Playgroud)

如果它是一个简单的行级触发器,那么我可以使用:new.fooId获取fooId.但事实并非如此.那么,我可以获得或给出INSERT ALL Trigger的ID吗?

谢谢.

Vin*_*rat 5

INSERT ALL是一个特例INSERT,它将触发标准BEFORE/AFTER INSERT触发器.

您需要ON EACH ROW触发器来访问要插入的行的值.(un)幸运的是,你不能使用行触发器来查询你想要修改的表:你会遇到ORA-04091.如果您想要执行此类逻辑,请参阅此最近的问题,了解为何不应使用触发器.

使用程序.更易于编码,更易于维护和调试.触发器是GOTO数据库逻辑.

以下是Tom Kyte提出的类似建议:

无论如何,你可以在触发器中做太多工作,这可能就是那个时候 - 以更直接的方式做事情没有错(例如:使用存储过程来实现你的事务)[...]
逻辑这种方式更容易理解(可维护和可测试的一切)


事后来看,你的情况比起初我想的要复杂得多.现在我对您的要求的理解是:您希望您的语句首先删除所有具有fooID标识符的行,然后插入另一组行.但是,行数可能不同,因此标准的每行行方法不起作用.

我现在甚至不确定你能用触发器做到这一点,即使你持续采用这种方法!

  • 如果我正确理解了这个问题,合并将无效.海报在fooID上匹配,对于合并集中的所有行都是相同的.这导致了ORA-30926.此外,您不能将序列与UNION一起使用.我认为您使用程序的原始建议仍然是最佳答案.不要以为我知道这一切都是我的头脑 - 我还以为MERGE才是答案,直到我尝试并跑进这些不同的砖墙:) (2认同)