Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

ORA-04091: table is mutating, trigger/function may not see it

B_BrockAug 6 2020 — edited Aug 7 2020

I have an AFTER INSERT trigger that attempts to summarize some data from the submitted row, and then UPDATE the row with the summarized figures.

I am getting ORA-04091 when I attempt to insert a new row.

I *could* insert the summarized data in a separate table that references the main table, but I would really like to understand the reason why the error is surfacing. I thought that if I was performing the update on an AFTER INSERT trigger, it should work?

Here's the code for my trigger.

Thank you.

Brian

---

create or replace trigger "SES_SCREENINGS_AI_SCORE"

AFTER

insert on "SES_SCREENINGS"

for each row

declare

       

    ln_emotional_scale_score                number(2);

    ln_Conduct_scale_score                  number(2);

    ln_hyper_scale_score                    number(2);

    ln_peer_scale_score                     number(2);

    ln_prosocial_scale_score                number(2);

    ln_total_difficulties_score             number(2);

    ln_externalizing_score                  number(2);

    ln_internalizing_score                  number(2);

    lv_emotional_score_category             varchar2(32);

    lv_conduct_score_category               varchar2(32);

    lv_hyper_score_category                 varchar2(32);

    lv_peer_score_category                  varchar2(32);

    lv_prosocial_score_category             varchar2(32);

    lv_total_difficulties_score_category    varchar2(32);

    lv_datasheet_required                   varchar2(1);

begin

    ln_emotional_scale_score     := :new.EMOTIONAL_1 + :new.EMOTIONAL_2 + :new.EMOTIONAL_3 + :new.EMOTIONAL_4 + :new.EMOTIONAL_5;

    ln_conduct_scale_score       := :new.CONDUCT_1 + :new.CONDUCT_2 + :new.CONDUCT_3 + :new.CONDUCT_4 + :new.CONDUCT_5;

    ln_hyper_scale_score         := :new.HYPER_1 + :new.HYPER_2 + :new.HYPER_3 + :new.HYPER_4 + :new.HYPER_5;

    ln_peer_scale_score          := :new.PEER_1 + :new.PEER_2 + :new.PEER_3 + :new.PEER_4 + :new.PEER_5;

    ln_prosocial_scale_score     := :new.PROSOCIAL_1 + :new.PROSOCIAL_2 + :new.PROSOCIAL_3 + :new.PROSOCIAL_4 + :new.PROSOCIAL_5;

   

    ln_total_difficulties_score  := ln_emotional_scale_score + ln_conduct_scale_score + ln_hyper_scale_score + ln_peer_scale_score;

    ln_externalizing_score       := ln_conduct_scale_score + ln_hyper_scale_score;

    ln_internalizing_score       := ln_emotional_scale_score + ln_peer_scale_score;

   

    -- categorize emotional_scale_score

    SELECT DESCRIPTION INTO lv_emotional_score_category

    FROM SES_CUTSCORES

    WHERE UPPER(SCREEN_TYPE) = UPPER(:new.screening_type)

    AND UPPER(SCORE_TYPE) = 'EMOTIONAL'

    AND UPPER(STATUS) = 'A'

    AND ln_emotional_scale_score BETWEEN LOW AND HIGH;

   

    -- categorize conduct_scale_score

    SELECT DESCRIPTION INTO lv_conduct_score_category

    FROM SES_CUTSCORES

    WHERE UPPER(SCREEN_TYPE) = UPPER(:new.screening_type)

    AND UPPER(SCORE_TYPE) = 'CONDUCT'

    AND UPPER(STATUS) = 'A'

    AND ln_conduct_scale_score BETWEEN LOW AND HIGH;

   

    -- categorize hyper_scale_score

    SELECT DESCRIPTION INTO lv_hyper_score_category

    FROM SES_CUTSCORES

    WHERE UPPER(SCREEN_TYPE) = UPPER(:new.screening_type)

    AND UPPER(SCORE_TYPE) = 'HYPER'

    AND UPPER(STATUS) = 'A'

    AND ln_hyper_scale_score BETWEEN LOW AND HIGH;

   

    -- categorize peer_scale_score

    SELECT DESCRIPTION INTO lv_peer_score_category

    FROM SES_CUTSCORES

    WHERE UPPER(SCREEN_TYPE) = UPPER(:new.screening_type)

    AND UPPER(SCORE_TYPE) = 'PEER'

    AND UPPER(STATUS) = 'A'

    AND ln_peer_scale_score BETWEEN LOW AND HIGH;

   

    -- categorize prosocial_scale_score

    SELECT DESCRIPTION INTO lv_prosocial_score_category

    FROM SES_CUTSCORES

    WHERE UPPER(SCREEN_TYPE) = UPPER(:new.screening_type)

    AND UPPER(SCORE_TYPE) = 'PROSOCIAL'

    AND UPPER(STATUS) = 'A'

    AND ln_prosocial_scale_score BETWEEN LOW AND HIGH;

   

    -- categorize total_difficulties_score

    SELECT DESCRIPTION INTO lv_total_difficulties_score_category

    FROM SES_CUTSCORES

    WHERE UPPER(SCREEN_TYPE) = UPPER(:new.screening_type)

    AND UPPER(SCORE_TYPE) = 'TOTAL'

    AND UPPER(STATUS) = 'A'

    AND ln_total_difficulties_score BETWEEN LOW AND HIGH;

   

    -- update the inserted row with calculated values

    UPDATE ses_screenings

    SET emotional_scale_score             = ln_emotional_scale_score,

        conduct_scale_score               = ln_conduct_scale_score,

        hyper_scale_score                 = ln_hyper_scale_score,

        peer_scale_score                  = ln_peer_scale_score,

        prosocial_scale_score             = ln_prosocial_scale_score,

        total_difficulties_score          = ln_total_difficulties_score,

        externalizing_score               = ln_externalizing_score,

        internalizing_score               = ln_internalizing_score,

        emotional_score_category          = lv_emotional_score_category,

        conduct_score_category            = lv_conduct_score_category,

        hyper_score_category              = lv_hyper_score_category,

        peer_score_category               = lv_peer_score_category,

        prosocial_score_category          = lv_prosocial_score_category,

        total_difficulties_score_category = lv_total_difficulties_score_category

   

    WHERE id = :new.id;

end;

/

This post has been answered by Mike Kutz on Aug 6 2020
Jump to Answer
Comments
Post Details
Added on Aug 6 2020
7 comments
2,470 views