下面的代码给出了一个变异错误。 任何人都可以帮助解决这个问题。

    CREATE OR REPLACE TRIGGER aso_quote_cuhk_trigger
    BEFORE INSERT
    ON aso.aso_quote_headers_all
    FOR EACH ROW
    BEGIN
     UPDATE aso.aso_quote_headers_all
     SET quote_expiration_date=sysdate+90
     where quote_header_id=:new.quote_header_id;
    END;
    /

===============>>#1 票数:8

在oracle中有两个级别的触发器:行级和表级。

for each row执行行级触发器。 即使语句更改了多行,也会对每个语句执行表级触发器。
在行级触发器中,您无法选择/更新具有触发器的表本身:您将收到变异错误。

在这种情况下,不需要UPDATE语句。 试试这个:

CREATE OR REPLACE TRIGGER aso_quote_cuhk_trigger
BEFORE INSERT
ON aso.aso_quote_headers_all
FOR EACH ROW
BEGIN
 :new.quote_expiration_date=sysdate+90;     
END;
/

编辑 Rajesh提到有可能,在插入新行之前,OP想要更新aso_quote_headers_all表中的所有其他记录。

嗯,这是可行的,但这有点棘手。 要做到这一点,你需要

  1. 一个pl / sql包和一个由触发器修改的包头中的变量。 该变量可以是包含新插入记录的ID的列表。 插入触发器后的行级别将向列表中添加新ID。 对于每个不同的会话,此包变量的内容将有所不同,因此我们将此变量称为session_variable
  2. 插入触发器后的行级别,将向session_variable添加新ID。
  3. 插入触发器之后的表级别,它将从session_variable获取ID,处理该ID,然后将其从session_variable删除。 此触发器可以在aso_quote_headers_all上执行必要的选择/更新。 处理新插入的ID后,此触发器应确保从session_variable删除它。

===============>>#2 票数:3

我知道你现在必须解决你的问题。 但是,我在下面添加这个答案,以帮助其他任何面临与您和我面临的类似问题的人。

我最近遇到变异表(ORA-04091:表XXXX正在变异,触发/功能可能看不到它)问题,并且在搜索后实现了11g中可用的复合触发功能。 如果您使用11g以下复合触发器就可以解决您的问题。

CREATE OR REPLACE TRIGGER aso_quote_cuhk_trigger
FOR INSERT ON aso.aso_quote_headers_all
COMPOUND TRIGGER

    row_id    rowid;

    AFTER EACH ROW IS
    BEGIN
      row_id := :new.rowid;
    END AFTER EACH ROW;

    AFTER STATEMENT IS
    BEGIN
      UPDATE aso.aso_quote_headers_all 
      SET quote_expiration_date = sysdate+90 
      WHERE rowid = row_id;
    END AFTER STATEMENT;
END aso_quote_cuhk_trigger;
/

关于它是如何工作的一个词。 此复合触发器触发2个事件:

  1. 首先是AFTER EACH ROW,我们捕获新插入行的rowid
  2. 接下来是AFTER STATEMENT,我们在WHERE子句中使用rowid(在第一个事件期间捕获)更新表。

如果您想了解有关复合触发器的更多信息,请使用这个链接

  ask by user978417 translate from so

未解决问题?本站智能推荐: