插入触发器后发生变异错误

use*_*417 2 oracle plsql

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

    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;
    /
Run Code Online (Sandbox Code Playgroud)

bpg*_*rgo 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;
/
Run Code Online (Sandbox Code Playgroud)

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

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

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