2

我想在插入更多行之前创建一个触发器。在插入新数据之前,我想通过 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;

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

谢谢。

4

2 回答 2

5

INSERT ALL是 的特例INSERT,它会触发标准BEFORE/AFTER INSERT触发器。

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

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

这是来自 Tom Kyte的类似建议:

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


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

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

于 2013-03-06T15:52:01.363 回答
1

我不知道有任何可靠的关系数据库可以在从同一个转录语句插入表的同时删除或更新表。
然而,这正是你想要做的。它被称为变异表。
我知道甲骨文不会让这个。
在您的示例中插入时您想插入一些数据,因此会有一个递归操作。
解决方案不会使用触发伙伴。

于 2013-03-06T16:00:09.450 回答