As already noted in the comments, it is somewhat meaningless to refer to the entire table being changed in the line-by-line trigger. Only to the line that is specifically modified by: new and: old pseudo-entries. Cycles, if there are no references to a variable table in them, nothing to do with it. Mutation in the first select in your code. But if you really want, you can:
create table mails (id number, mail varchar2(64)); --Table MAILS created. insert into mails select * from ( select 1, 'my@mail.ru' from dual union all select 2, 'other(at)mail.ru' from dual ); --2 rows inserted. create or replace trigger mails_trig before update of mail on mails for each row declare misformatted number; begin select count(1) into misformatted from mails where mail is not null and not regexp_like(mail, '\w+@\w+\.\w+') ; --dbms_output.put_line('alrady misformatted emails ' || misformatted || ' checked by update row ' || :old.id || '/' || :old.mail); end; / --Trigger MAILS_TRIG compiled update mails set mail = '_' || mail where id=1; SQL Error: ORA-04091: table SH1.MAILS is mutating, trigger/function may not see it ORA-06512: at "SH1.MAILS_TRIG", line 4 ORA-04088: error during execution of trigger 'SH1.MAILS_TRIG' 04091. 00000 - "table %s.%s is mutating, trigger/function may not see it" *Cause: A trigger (or a user defined plsql function that is referenced in this statement) attempted to look at (or modify) a table that was in the middle of being modified by the statement which fired it. *Action: Rewrite the trigger (or function) so it does not read that table. --Error report - --SQL Error: ORA-04091: table SH1.MAILS is mutating, trigger/function may not see it
How not to agree, we will rewrite
create or replace trigger mails_trig before update of mail on mails for each row declare function foundMisformatted return boolean is misformatted number; pragma autonomous_transaction; begin select count(1) into misformatted from mails where mail is not null and not regexp_like(mail, '\w+@\w+\.\w+') ; dbms_output.put_line('mails_trig: alrady misformatted emails ' || misformatted || ' - checked by update row ' || :old.id || '/' || :old.mail); return misformatted>0; end; begin if foundMisformatted then --raise_application_error(-20009, 'misformatted mails.mail found'); --ΠΈΠ»ΠΈ, ΡΡΠΎ-ΡΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΆΠΈΠ·Π½Π΅Π½ΠΎΠ΅ - ΠΏΡΡΠΊΠ°ΠΉ Π½Π΅ΠΎΠΏΡΡΠ½ΡΠΉ ΠΊΠΎΠ»Π»Π΅Π³Π° Π΄Π΅Π½ΡΠΊ ΠΎΡΠΈΠ±ΠΊΡ ΠΏΠΎΠΈΡΠ΅Ρ dbms_output.put_line('mails_trig: warning: misformatted mails.mail found'); :new.mail := :old.mail; return; end if; -- do anything end; / --Trigger MAILS_TRIG compiled update mails set mail = '_' || mail where id=1; mails_trig: alrady misformatted emails 1 - checked by update row 1/my@mail.ru mails_trig: warning: misformatted mails.mail found drop trigger mails_trig; drop table mails;
:new.semail. no cycles and select is necessary, the DB will do everything for you - Mikefor each row- Mike