我想在插入更多行之前创建一个触发器。 在插入新数据之前,我想删除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。
答案 0 :(得分:5)
INSERT ALL
是INSERT
的特例,会触发标准的BEFORE/AFTER INSERT
触发器。
您需要ON EACH ROW
个触发器才能访问要插入的行的值。 (un)幸运的是,您不能使用行触发器来查询您要修改的表:您将遇到ORA-04091
。如果你想要做这种逻辑,请参阅此recent question,了解为什么不应该使用触发器。
使用程序。更易于编码,更易于维护和调试。触发器是数据库逻辑的GOTO
。
这是一个类似的advice from Tom Kyte:
无论如何,你可以在触发器中做太多的工作,这可能就是那个时候 - 有 以更直接的方式做事情没有错(例如:使用存储的 实施交易的程序)[...]
这种逻辑更容易理解(并且 可维护和可测试的一切)
事后看来,你的情况比起初的想法更复杂。现在我对您的要求的理解是:您希望您的语句首先删除所有具有fooID
标识符的行,然后插入另一组行。但是,行数可能不同,因此标准的每行行方法将不起作用。
我现在甚至不确定你是否可以使用触发器执行此操作,即使您坚持使用此方法!
答案 1 :(得分:1)
我不知道任何可靠的关系数据库,它允许在从同一个转录语句插入表的同时删除或更新表。
但这就是你想要做的。它被称为变异表。我知道甲骨文不会放过这个。
在您插入想要插入一些数据的示例中,将进行递归操作
解决方案不会使用触发器。