PL / SQL Mutating Trigger - 另类想法?

时间:2016-04-18 15:03:19

标签: 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
    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;
/

2 个答案:

答案 0 :(得分:0)

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

  • 将触发器更改为后触发器。
  • 将其从行级触发器更改为语句级触发器。
  • 转换为复合触发器。
  • 使触发器自动进行提交。

答案 1 :(得分:0)

如果要逐行修改值,则不需要在触发器内进行更新。
然后运行你的案子

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;