Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle PL/SQL变异触发器-替代方案?_Oracle_Plsql_Triggers - Fatal编程技术网

Oracle PL/SQL变异触发器-替代方案?

Oracle PL/SQL变异触发器-替代方案?,oracle,plsql,triggers,Oracle,Plsql,Triggers,下面的代码用于在插入新记录时触发,并用于更改新记录的字段,但在尝试插入时出现了一个变异错误。我能做些什么来解决这个问题 CREATE OR REPLACE TRIGGER trig_auto_rating_desc AFTER INSERT ON reviews FOR EACH ROW DECLARE vn_rating NUMBER(1); vc_rating_description reviews.rating_description%TYPE := ''; BEGIN

下面的代码用于在插入新记录时触发,并用于更改新记录的字段,但在尝试插入时出现了一个变异错误。我能做些什么来解决这个问题

CREATE OR REPLACE TRIGGER trig_auto_rating_desc
AFTER INSERT ON reviews
FOR EACH ROW

DECLARE
    vn_rating NUMBER(1);
    vc_rating_description reviews.rating_description%TYPE := '';

BEGIN
    vn_rating := :NEW.overall_rating;
    CASE vn_rating
        WHEN 1 THEN vc_rating_description := 'VERY POOR';
        WHEN 2 THEN vc_rating_description := 'POOR';
        WHEN 3 THEN vc_rating_description :='OKAY';
        WHEN 4 THEN vc_rating_description := 'GOOD';
        WHEN 5 THEN vc_rating_description := 'VERY GOOD';
        ELSE dbms_output.put_line('NO SUCH REVIEW');
    END CASE;

    dbms_output.put_line(vn_rating || ' = ' || vc_rating_description);
    UPDATE reviews SET rating_description = vc_rating_description WHERE review_id = :NEW.review_id;

END trig_auto_rating_desc;
/

当一条语句导致触发触发器,并且该触发器引用导致该触发器的表时,就会发生一个变异表。避免此类问题的最佳方法是不要使用触发器,或者您可以尝试以下方法:

  • 将触发器更改为后触发器
  • 将其从行级触发器更改为语句级触发器
  • 转换为复合触发器
  • 使触发器具有自治性,其中包含提交

当一条语句导致触发一个触发器,而该触发器引用导致该触发器的表时,就会发生一个变异表。避免此类问题的最佳方法是不要使用触发器,或者您可以尝试以下方法:

  • 将触发器更改为后触发器
  • 将其从行级触发器更改为语句级触发器
  • 转换为复合触发器
  • 使触发器具有自治性,其中包含提交

如果要逐行修改值,则无需在触发器中进行更新。
那就去办你的案子吧

CREATE OR REPLACE TRIGGER trig_auto_rating_desc
BEFORE INSERT
ON REVIEWS
REFERENCING NEW AS New OLD AS Old
FOR EACH ROW

DECLARE
    vn_rating NUMBER(1);
    vc_rating_description reviews.rating_description%TYPE := '';

BEGIN
    vn_rating := :NEW.overall_rating;
    CASE vn_rating
        WHEN 1 THEN vc_rating_description := 'VERY POOR';
        WHEN 2 THEN vc_rating_description := 'POOR';
        WHEN 3 THEN vc_rating_description :='OKAY';
        WHEN 4 THEN vc_rating_description := 'GOOD';
        WHEN 5 THEN vc_rating_description := 'VERY GOOD';
        ELSE vc_rating_description := 'Invalid value';
        --you will never see dbms_output from a trigger
        --ELSE dbms_output.put_line('NO SUCH REVIEW');
    END CASE;
    :new.rating_description := vc_rating_description;

END trig_auto_rating_desc;

如果要逐行修改值,则无需在触发器内执行更新。
那就去办你的案子吧

CREATE OR REPLACE TRIGGER trig_auto_rating_desc
BEFORE INSERT
ON REVIEWS
REFERENCING NEW AS New OLD AS Old
FOR EACH ROW

DECLARE
    vn_rating NUMBER(1);
    vc_rating_description reviews.rating_description%TYPE := '';

BEGIN
    vn_rating := :NEW.overall_rating;
    CASE vn_rating
        WHEN 1 THEN vc_rating_description := 'VERY POOR';
        WHEN 2 THEN vc_rating_description := 'POOR';
        WHEN 3 THEN vc_rating_description :='OKAY';
        WHEN 4 THEN vc_rating_description := 'GOOD';
        WHEN 5 THEN vc_rating_description := 'VERY GOOD';
        ELSE vc_rating_description := 'Invalid value';
        --you will never see dbms_output from a trigger
        --ELSE dbms_output.put_line('NO SUCH REVIEW');
    END CASE;
    :new.rating_description := vc_rating_description;

END trig_auto_rating_desc;

我已经把它作为后触发器了,所以我不明白为什么会出现这个错误,它会在插入行后更新行,除非它在触发器完成后才真正插入?您可以尝试使用自治事务自治事务不是这里的解决方案(而且,总的来说,对于任何触发器)@Globin>您需要了解触发器。我建议看一看,您可以看到
后触发器无法更改新字段值,因为触发语句在触发器触发之前运行。
。换句话说,您可以在插入行之前更改插入的值,但一旦插入了行,就到此为止。正如我上面所说,在触发器之前使用
,或者将更改作为insert语句的一部分。@Boneist再次感谢您的建议,它工作得很好。我已经将它作为后触发器使用,所以我不明白为什么会出现此错误,它会在插入行之后更新行,除非它在触发器完成后才真正插入?您可以尝试使用自治事务自治事务不是这里的解决方案(总体而言,对于任何触发器)@Globin>您需要了解触发器。我建议看一看,您可以看到
后触发器无法更改新字段值,因为触发语句在触发器触发之前运行。
。换句话说,您可以在插入行之前更改插入的值,但一旦插入了行,就到此为止。正如我上面所说的,在触发器之前使用
,或者在insert语句中进行更改。@Boneist再次感谢您的建议,它工作得很好感谢您的回复,我收到一个错误:new.rating\u description=vc\u rating\u description,这是不是意味着“:”?我说出来还是有错误“无法更改此触发器类型的新值“在线路上出错1@theglobin这是因为您正在使用
AFTER
触发器。在触发器之前将其切换到
,它应该可以工作。或者,您也可以在insert语句本身中执行case语句。@Boneist谢谢!这就是解决方案,一切都很完美:)感谢您的回复,我在这行上收到了一个错误:new.rating_description=vc_rating_description,这是不是意味着“:”?“我仍然收到一个错误,说它“无法更改此触发器类型的新值”在线路上出错1@theglobin这是因为您正在使用
AFTER
触发器。在触发器之前将其切换到
,它应该可以工作。或者,您也可以在insert语句本身中执行case语句。@Boneist谢谢!这就是解决方案,一切都很完美:)