Oracle之前插入所有触发器

时间:2013-03-06 15:15:38

标签: oracle triggers insert

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

e.g:

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;

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

THX。

2 个答案:

答案 0 :(得分:5)

INSERT ALLINSERT的特例,会触发标准的BEFORE/AFTER INSERT触发器。

您需要ON EACH ROW个触发器才能访问要插入的行的值。 (un)幸运的是,您不能使用行触发器来查询您要修改的表:您将遇到ORA-04091。如果你想要做这种逻辑,请参阅此recent question,了解为什么不应该使用触发器。

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

这是一个类似的advice from Tom Kyte

  

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


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

我现在甚至不确定你是否可以使用触发器执行此操作,即使您坚持使用此方法

答案 1 :(得分:1)

我不知道任何可靠的关系数据库,它允许在从同一个转录语句插入表的同时删除或更新表。
但这就是你想要做的。它被称为变异表。我知道甲骨文不会放过这个。
在您插入想要插入一些数据的示例中,将进行递归操作 解决方案不会使用触发器。