【问题标题】:Oracle before insert all trigger插入所有触发器之前的Oracle
【发布时间】:2013-03-06 15:15:37
【问题描述】:

我想在插入更多行之前创建一个触发器。 在插入新数据之前,我想通过 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。 但事实并非如此。 那么,我可以为 INSERT ALL Trigger 获取或提供 id 吗?

谢谢。

【问题讨论】:

    标签: oracle triggers insert


    【解决方案1】:

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

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

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

    这是一个类似的advice from Tom Kyte

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


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

    我现在甚至不确定你是否可以使用触发器来做到这一点,即使你坚持使用这种方法

    【讨论】:

    • 如果我正确理解了这个问题,合并将不起作用。海报在 fooID 上匹配,这对于合并集中的所有行都是相同的。这会导致 ORA-30926。此外,您不能将序列与 UNION 一起使用。我认为您使用程序的原始建议仍然是最好的答案。不要以为我一无所知 - 我还认为 MERGE 是答案,直到我尝试它并遇到这些不同的砖墙 :)
    • insert all 方法也会为所有行获得相同的序列值,这是不使用它的另一个原因。这个answer 有一个相关文档的链接。
    • @alexpoole 出于某种原因我认为它会得到不同的 id,感谢您的更正:)
    • merge 将获得不同的 ID,insert all 不会,根据该链接。您不能将nextval 移动到值子句中,而不是在联合中生成它吗?合并似乎在fooid 上匹配column2,而不是column1,它正在获取nextval,所以你不希望它在on 子句中......我认为......虽然从你的最新更新我认为无论如何我都过于简单化了。
    • @alexpoole 我认为问题更复杂:匹配将在非唯一列上完成,因此无法使用合并!
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-25
      • 2022-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多