Mutating table error in Trigger

i was asked to create a trigger like...
1. whenever a row inserted into TFILE, a select statment will be used to bring some data from different tables using a join(including FILE_TABLE)
and then inserting selected values into a new table NEW_TAB.
2. whenever a row Deleted from TFILE table, That curresponding row should be deleted from NEW_TAB.
i Tried Like....
create or replace
TRIGGER my_trigger
AFTER INSERT OR DELETE
ON tfile
FOR EACH ROW
DECLARE
V_FILE_ID NUMBER(8);
V_PROP_ID NUMBER(8);
V_DOC_ID NUMBER(8);
V_TEMP_FILE_ID NUMBER(8);
BEGIN
IF INSERTING THEN
SELECT B.DOC_ID,
B.PROP_ID,
A.FILE_ID
INTO V_DOC_ID,
V_PROP_ID,
V_FILE_ID
FROM (SELECT DOC_ID,
FILE_ID
FROM DOC_FILE
WHERE FILE_ID = (SELECT FILE_ID
FROM TFILE
WHERE FILE_ID = :NEW.FILE_ID)) A ,
DOC_OPPT B
WHERE B.DOC_ID = A.DOC_ID;
INSERT INTO NEW_TAB (SNO,FILE_ID,PROP_ID,DOC_ID)VALUES(CUST_COR_SEQ.NEXTVAL,V_FILE_ID,V_PROP_ID,V_DOC_ID);
END;
ELSIF DELETING THEN
DELETE FROM NEW_TAB WHERE FILE_ID = :OLD.FILE_ID;
END IF;
==================================================================
I am getting error like..
ORA-04091: table STARS.TFILE is mutating, trigger/function may not see it
ORA-06512: at "STARS.MY_TRIGGER", line 8
ORA-04088: error during execution of trigger 'STARS.MY_TRIGGER'
how to solve this....?
can anybody can explain solution for my problem with some good example please ?
thanks

Hi,
From Documentation
mutating table is a table that is currently being modified by an UPDATE, DELETE, or INSERT statement, or a table that might be updated by the effects of a DELETE CASCADE constraint.
*The session that issued the triggering statement cannot query or modify a mutating table*. This restriction prevents a trigger from seeing an inconsistent set of data.
This restriction applies to all triggers that use the FOR EACH ROW clause, and statement triggers that are fired as the result of a DELETE CASCADE
To avoid..an article by tom kyte.
http://asktom.oracle.com/pls/asktom/ASKTOM.download_file?p_file=6551198119097816936
Hope it helps,
CKLP                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

Similar Messages

  • Solve mutating table error

    Hi,
    I want a solution for mutating table error. I am a newbie in oracle.
    I'll explain my scenario.
    There are two tables TEACHER and STUDENT
    both are linked using the field 'tid'. the foreign key relation is given as ON DELETE CASCADE
    so if i delete a row from teacher , the corresponding rows in student get deleted, but i want to back up all the students who comes under that teacher, who is getting deleted.
    I tried in TRIGGER, but getting mutating table error.
    Please help
    Thanks in advance
    Divya

    This extract from an earlier post might be of help:
    You can solve this problem by using following thing
    1)create a view on same table with all fields
    and write trigger on table (insert,update or delete ) while inserting or updating or deleting row from table read from view.
    (Mutating error come when you are reading from one table and want to update,insert or delete row of same table).
    2)create a temporary table(but it is possible in 8i onword only) same as table on which you want to write trigger,while updating,inserting or deleting rows of table read from temporary table and after your work is over temporary table auotomatically drop (see proper command in oracle documentation to create temporary table).
    null

  • Mutating table error

    Hi All,
    I am getting the “ORA-04091 - mutating table error" when my trigger on a table "fnd_flex_values" fires. As I understand it, this error is occuring because, the users are trying to add rows to this table (it is an after insert trigger) and the trigger is trying to get values from the same table.
    Any suggestions on how to get around the mutating table error?
    My trigger code :
    CREATE OR REPLACE TRIGGER "APPS".ST_BU_PARENT_CC
    after insert on APPLSYS.FND_FLEX_VALUES REFERENCING OLD AS OLD NEW AS NEW
    for each row
    Declare
    v_flex_value    varchar2(150) :=null;
    v_desc          varchar2(2) := null;
    v_createdby     number      :=null;
    v_lstupdby      number      :=null;
    v_lstupdlogin   number      :=null;
    begin
      if inserting then
         select a.last_update_login,a.last_updated_by,a.created_by,a.flex_value,
                   rtrim(substr(description,instr(b.description,',')+1,5))
         into v_lstupdlogin,v_lstupdby,v_createdby,v_flex_value,v_desc
         from fnd_flex_values a,
                 fnd_flex_values_tl b
            where a.flex_value_id = b.flex_value_id
            and   a.flex_value_set_id = :new.flex_value_set_id
         and   a.flex_value_set_id = 1009635
            and   (a.flex_value like '1%' or a.flex_value like '7%')
         order by flex_value asc;
         insert into applsys.fnd_flex_value_hierarchies
            values(:new.flex_value_set_id,v_desc||'STO',v_flex_value,v_flex_value,sysdate,v_lstupdby,sysdate,v_createdby,null,null,null);
            insert into applsys.fnd_flex_value_norm_hierarchy
            values(:new.flex_value_set_id,v_desc||'STO','P',v_flex_value,v_flex_value,sysdate,v_lstupdby,sysdate,v_createdby,v_lstupdlogin,null,null);
      end if;
      exception
        when no_data_found then
          raise;
    end;Thanks,
    Chiru

    >>
    Any suggestions on how to get around the mutating
    table error?
    This link by Tom Kyte should help you with the
    "mutating table" error.
    http://asktom.oracle.com/tkyte/Mutate/index.html
    pratzPratz,
    Thanks for the quick reply. I am trying to create a temp table (log_table) but having the "insufficient privilages" issues.
    Thanks,
    Chiru

  • Mutation table error

    i am trying to updata any row at the time i am getting mutating table error for some triggers
    fired on that table.what is the resonn and how to solve this problem,plz..help

    Here's a good resource
    http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:290416059674

  • Mutating table exception on trigger with After Insert but not with before

    Hi
    I need to maintain some constraint on the table to have only one row for values of the columns but not by primary key constraint.
    Because in case of primary key the insert would fail and the rest of the operation would be discontinued, I cannot change in the somponent that inserts the row so I have to prevent that on the table I have.
    I created a before insert trigger on the table which checks if any row exists in the table with same column values as the one being inserted. if found I delete the rows and let the insert happen (w/o raising any error). if the rows do not exist then the insert shall be continued.
    I read at place that modifying the dame table in the trigger body shall raise a mutating table exception, but I donot get the exception when the trigger is fired.
    Just when I change the trigger to after insert trigger then the nutating table exception is thrown.
    Is it the right behavior i.e. the Before insert trigger does not raise the exception and only after insert does that, since I could not find the example for before insert triggers throwing such exception so I think it is better to confirm it before finalizing the implementation.
    Thanks
    Sapan

    sapan wrote:
    Hi Tubby
    I cannot user unique constraint because that would raise an exception upon violation and the third party component that is inserting in the table would fail.
    That component does some other tasks as well after this insert and if an exception is raised then those tasks would not be performed.
    Also I cannot change the component to ignore this exception.Well then, you're in a bit of a pickle.
    I'm guessing the trigger you have been working on isn't "safe". By that i mean that it doesn't account for multi-user scenarios. You'll need to serialize access to the data elements in question and implement some sort of locking mechanism to ensure that only 1 session can work with those values.
    After you work out how to do that it sounds as though you would be better served using an INSTEAD OF trigger (you'd need to implement this on a view which is made off of your base table).
    Here's one way you can work on serializing access to your table on a relatively fine grained level (as opposed to locking the entire table).
    Re: possible to lock stored procedure so only one session may run it at a time?
    Cheers,

  • ORA-04091 mutating table error

    Hi,
    Using Oracle 8.1.7 on Windows 2000.
    I am trying to write a trigger that fires at each insert my Java application executes in my_table, when the trigger is supposed to update, on the just inserted row, the code field.
    I created my trigger to fire AFTER and on INSERT, on each row with the following body:
    DECLARE
    v_max_code my_table.code%TYPE;
    BEGIN
    SELECT MAX(code) INTO v_max_code FROM my_table;
    v_max_code := v_max_code + 1;
    UPDATE my_table SET code = v_max_code;
    END;
    When the insert was attempted I got the "ORA-04091 Table is mutating, trigger/function may not see it
    " error and the transaction was rolled back.
    I modified the triger "on statement" and it worked, bit it updated all the code fields from the table, not only the one from the inserted row, which is not surprising, because I didn't add a where clause for the update statement.
    My questions are:
    - Is it possible to use a "on each row" trigger to achieve the update after insert?
    - How should tell Oracle to update only the code for the just inserted row?
    Thanks in advance,
    Paul

    Hello
    You need a combination of before statement, after row and after statement to get round this:
    http://osi.oracle.com/~tkyte/Mutate/index.html
    Also, is more than one person going to insert into this table at once? If so, you run the risk of 2 people selecting the same max code at the same time and so 2 rows could end up with the same code. Just a suggestion but this looks like it could be better served with a sequence, and you may be able to get rid of the trigger all together.
    HTH
    David

  • How to solve mutating table error?

    I compiled the trigger below successfully:
    CREATE OR REPLACE TRIGGER avail_products
    BEFORE INSERT ON orders_tbl
    FOR EACH ROW
    DECLARE
    m_prodqty products_tbl.prod_qty%TYPE;
    m_ordered orders_tbl.ord_qty%TYPE;
    m_prodid orders_tbl.prod_id%TYPE;
    BEGIN
    SELECT p.prod_qty, o.ord_qty, o.prod_id
    INTO m_prodqty, m_ordered, m_prodid
    FROM products_tbl p, orders_tbl o
    WHERE ord_num=:NEW.ord_num;
    IF m_prodqty>=m_ordered THEN
    UPDATE products_tbl
    SET prod_qty=prod_qty-m_ordered
    WHERE prod_id=m_prodid;
    ELSE
    RAISE_APPLICATION_ERROR(-20101,'Product is not available');
    END IF;
    END;
    However, when I run my PL/SQL block as follows:
    DECLARE
    v_max NUMBER;
    BEGIN
    SELECT MAX(ord_num)+1
    INTO v_max
    FROM orders_tbl;
    INSERT INTO orders_tbl(ord_num, cust_id, prod_id, ord_qty, ord_date, dvy_date, refund)
    VALUES (v_max, &cust_id, &prod_id, &ord_qty, '&ord_date', '&dvy_date',0);
    COMMIT;
    END;
    UPDATE orders_tbl
    SET refund=0.1*(SELECT price FROM products_tbl WHERE prod_id=(SELECT prod_id FROM orders_tbl WHERE ord_num=(SELECT MAX(ord_num) FROM orders_tbl)))
    WHERE ord_num = (SELECT MAX(ord_num) FROM orders_tbl) AND dvy_date>ord_date+3;
    COMMIT;
    It gives me these errors:
    ERROR at line 1:
    ORA-01403: no data found
    ORA-01403: no data found
    ORA-06512: at "SYSTEM.AVAIL_PRODUCTS", line 9
    ORA-04088: error during execution of trigger 'SYSTEM.AVAIL_PRODUCTS'
    ORA-06512: at line 10
    I try to debug it again and again but still can't find the mistake. So I change the trigger option to AFTER INSERT, then I got the error message that the table is mutating and trigger migh not see it. Anyone know how to solve this problem?
    ERROR at line 2:
    ORA-04091: table SYSTEM.ORDERS_TBL is mutating, trigger/function may not see it
    ORA-06512: at "SYSTEM.AVAIL_PRODUCTS", line 13
    ORA-04088: error during execution of trigger 'SYSTEM.AVAIL_PRODUCTS'
    null

    This extract from an earlier post might be of help:
    You can solve this problem by using following thing
    1)create a view on same table with all fields
    and write trigger on table (insert,update or delete ) while inserting or updating or deleting row from table read from view.
    (Mutating error come when you are reading from one table and want to update,insert or delete row of same table).
    2)create a temporary table(but it is possible in 8i onword only) same as table on which you want to write trigger,while updating,inserting or deleting rows of table read from temporary table and after your work is over temporary table auotomatically drop (see proper command in oracle documentation to create temporary table).
    null

  • Trying to automatically add a new row w/o mutating table error...

    I'm using Oracle 10g express. I'm trying to automatically add a new row with the same e_ID, (RDD + 6 months) as the updated row when RC is updated. I'm fairly new to Oracle, so I need some help on creating a trigger. If you need more details let me know. Thanks in advance.
    create table E
    e_id number(6,0) not null,
    constraint e_pk primary key(e_id)
    create Table ER
    e_Id Number(6,0) Not Null,
    SC Date,
    RDD Date,
    RC Date,
    Constraint ER_Fk Foreign Key(E_Id) References E(E_Id)
    );

    mookjais wrote:
    I'm using Oracle 10g express. I'm trying to automatically add a new row with the same e_ID, (RDD + 6 months) as the updated row when RC is updated. I'm fairly new to Oracle, so I need some help on creating a trigger. If you need more details let me know. Thanks in advance.
    create table E
    e_id number(6,0) not null,
    constraint e_pk primary key(e_id)
    create Table ER
    e_Id Number(6,0) Not Null,
    SC Date,
    RDD Date,
    RC Date,
    Constraint ER_Fk Foreign Key(E_Id) References E(E_Id)
    );Do you mean following(example)?
    create trigger after_insert_e
    after
      insert
    on  e /*This is table name*/
    referencing new as new old as old
    for each row
    begin
    insert into  ER(e_Id,SC,rdd,rc)
    values(:new.ed_id,sysdate,sysdate,sysdate);
    end;

  • Error in trigger

    Hi,
    I am stuck with the error PLS-00103.
    Actually what I want to do is, I have a table user_info which holds the details about the users like passwords.
    Each time a user updates a password in the table, the new password should go into the varrying array old_passwords, which is an attribute in the table. If the number of passwords are equal to the size(i.e 10) of the array then,
    the new password which is being updated should be checked whether it is already there in the last 10 passwords,
    if it is there then I have to raise an exception, otherwise I have to trim the last password from the array and add the new password to the first position of the array.
    And for inserting the passwords I have a procedure called add_password which takes a varying object and the new password as parameters. I have written the code in order to avoid the mutating table error.
    I am showing all that I have done, I wil be very thankful, if anyone can suggest me a way to solve the problem.
    -- Table user_info
    create table User_Info(Name varchar2(20),
    Passwd varchar2(10),
    E_Mail varchar2(30) constraint email_pk primary key deferrable initially immediate,
    Rank varchar2(20),
    Country varchar2(30) constraint user_fk references country, Passwd_Change_Date date,
    Last_Login date,
    Old_Passwords Old_Passwds_Ty,
    constraint uname_uq unique(name));
    -- package to avoid mutating table error
    create or replace package new_pas as
    type pwd_ty is table of user_info%rowtype index by binary_integer;
    upwd_table pwd_ty;
    end new_pas;
    --after row level trigger to store new values
    create or replace trigger b_trig
    after update of passwd on user_info
    for each row
    begin new_pas.upwd_table(new_pas.upwd_table.count+1).passwd:=:new.passwd; new_pas.upwd_table(new_pas.upwd_table.count+1).name:=:old.name;
    end b_trig;
    -- after statement level trigger
    create or replace trigger trig_pass after update of passwd on user_info
    begin
    declare old_pass old_passwds_ty;
    begin select old_passwords into old_pass from user_info where name=new_pas.upwd_table(new_pas.upwd_table.count+1).name;
    if old_pass is null or old_pass.count<old_pass.limit then
    add_password(old_passwds_ty('some'),new_pas.upwd_table(new_pas.upwd_table.count+1).passwd);
    elsif old_pass.count=old_pass.limit then
    for i in 1 .. old_pass.count loop
    if old_pass(i)=new_pas.upwd_table(new_pas.upwd_table.count+1).passwd then raise exceptions_package.Invalid_password;
    end if;
    end loop;
    add_password(old_passwds_ty('some'),new_pas.upwd_table(new_pas.upwd_table.count+1).passwd);
    new_pas.upwd_table.delete;
    end if;
    end trig_pass;
    -- The error while compiling this trigger is:
    37/0 PLS-00103: Encountered the symbol "end-of-file" when expecting one of the follow ing: begin case declare end exception exit for goto if loop mod null pragma raise return select update while with ><an identifier> << close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe
    -- The body of add_password is:
    create or replace procedure Add_password(user_pwd old_passwds_ty,pwd user_info.passwd%type) is
    new_pass old_passwds_ty;
    u_pwd old_passwds_ty;
    begin
    u_pwd:=user_pwd;
    for rec in (select old_passwords from user_info) loop
    u_pwd:=rec.old_passwords;
    if u_pwd is null then
    new_pass:=old_passwds_ty(pwd);
    elsif u_pwd.count=u_pwd.limit then
    new_pass:=old_passwds_ty(pwd);
    u_pwd.trim;
    for i in 1 .. u_pwd.count loop
    new_pass(i+1):=u_pwd(i);
    end loop;
    exit;
    end if;
    end loop;
    update user_info set old_passwords=new_pass; end add_password;
    Thanks for reading, I will be very thankful, If I can get a solution

    -- after statement level trigger
    create or replace trigger trig_pass after update of passwd on user_info
    begin
    declare old_pass old_passwds_ty;
    begin select old_passwords into old_pass from user_info where name=new_pas.upwd_table(new_pas.upwd_table.count+1).name;
    if old_pass is null or old_pass.count<old_pass.limit then
    add_password(old_passwds_ty('some'),new_pas.upwd_table(new_pas.upwd_table.count+1).passwd);
    elsif old_pass.count=old_pass.limit then
    for i in 1 .. old_pass.count loop
    if old_pass(i)=new_pas.upwd_table(new_pas.upwd_table.count+1).passwd then raise exceptions_package.Invalid_password;
    end if;
    end loop;
    add_password(old_passwds_ty('some'),new_pas.upwd_table(new_pas.upwd_table.count+1).passwd);
    new_pas.upwd_table.delete;
    end if;
    end;
    end trig_pass;
    Need one more end;
    /

  • Mutating table

    Hello,
    I have a table with srce_id,c_code and l_c_code. when ever data is uploaded into w_ty_e_ap table c_code value has to be copied to l_c_code based on srce_id.Input file has blank data for l_c_code.When I have written the below trigger I am getting:
    ORA-04091: table w_ty_e_ap is mutating, trigger/function may not see it
    Can you please advise me,
    Cheers,
    PSK
    CREATE OR REPLACE TRIGGER SA_TR_CO_CE_SM
    after INSERT
    ON w_ty_e_ap
    FOR EACH row
    DECLARE
    vno NUMBER;
    CURSOR c1
    IS
    SELECT c_code
    from w_ty_e_ap
    where srce_id=:new.srce_id
    for update of c_code;
    BEGIN
    open c1;
    loop
    fetch c1 into vno;
    if c1%notfound then
    VNO := 9999;
    else
    UPDATE w_ty_e_ap
    SET l_c_code = vno
    WHERE CURRENT OF c1;
    end if;
    end loop;
    close c1;
    END;
    /

    Hi ,
    I also paste the following proposed by Oracle .......about mutating tables
    A mutating table is a table that is being modified by an UPDATE, DELETE, or INSERT statement, or a table that might be updated by the effects of a DELETE CASCADE constraint.
    The session that issued the triggering statement cannot query or modify a mutating table. This restriction prevents a trigger from seeing an inconsistent set of data.
    This restriction applies to all triggers that use the FOR EACH ROW clause. Views being modified in INSTEAD OF triggers are not considered mutating.
    When a trigger encounters a mutating table, a runtime error occurs, the effects of the trigger body and triggering statement are rolled back, and control is returned to the user or application.
    Consider the following trigger:
    CREATE OR REPLACE TRIGGER Emp_count
    AFTER DELETE ON Emp_tab
    FOR EACH ROW
    DECLARE
        n INTEGER;
    BEGIN
        SELECT COUNT(*) INTO n FROM Emp_tab;
        DBMS_OUTPUT.PUT_LINE(' There are now ' || n ||
            ' employees.');
    END;
    If the following SQL statement is entered:
    DELETE FROM Emp_tab WHERE Empno = 7499;
    An error is returned because the table is mutating when the row is deleted:
    ORA-04091: table SCOTT.Emp_tab is mutating, trigger/function may not see it
    If you delete the line "FOR EACH ROW" from the trigger, it becomes a statement trigger which is not subject to this restriction, and the trigger.
    If you need to update a mutating table, you could bypass these restrictions by using a temporary table, a PL/SQL table, or a package variable. For example, in place of a single AFTER row trigger that updates the original table, resulting in a mutating table error, you might use two triggers—an AFTER row trigger that updates a temporary table, and an AFTER statement trigger that updates the original table with the values from the temporary table.
    Declarative integrity constraints are checked at various times with respect to row triggers.
    Because declarative referential integrity constraints are not supported between tables on different nodes of a distributed database, the mutating table restrictions do not apply to triggers that access remote nodes. These restrictions are also not enforced among tables in the same database that are connected by loop-back database links. A loop-back database link makes a local table appear remote by defining an Oracle Net path back to the database that contains the link.Regards,
    Simon

  • Mutating table confusion

    I am confused. I thought that if you tried to query a table from a BEFORE ROW trigger, which was the actual table upon which the BEFORE ROW trigger was applied against, you would get a MUTATING TABLE ERROR. For instance, I did not think that this would work:
    SQL> create table check_mte (tk number,
      2                          group_id number,
      3                          date_begin date,
      4                          date_end date);
    Table created.
    SQL> create or replace
      2  trigger check_mte
      3  before insert
      4  on check_mte
      5  for each row
      6  declare
      7    wk_cnt number;
      8  begin
      9    select count(*) into wk_cnt
    10      from check_mte a
    11     where a.tk != :new.tk
    12       and a.group_id = :new.group_id
    13       and (:new.date_begin, :new.date_end) overlaps (a.date_begin, a.date_end);
    14   
    15    if wk_cnt = 1 then
    16      raise_application_error(-20500, 'Overlapping date range error.');
    17    end if;
    18   
    19  end check_mte;
    20  /
    Trigger created.
    SQL> insert into check_mte values (1, 1, trunc(sysdate), trunc(sysdate)+1);
    1 row created.
    SQL> insert into check_mte values (2, 1, trunc(sysdate)+1, trunc(sysdate)+2);
    1 row created.
    SQL> insert into check_mte values (3, 1, trunc(sysdate)+2, trunc(sysdate)+3);
    1 row created.
    SQL> select * from check_mte;
            TK   GROUP_ID DATE_BEGI DATE_END
             1          1 25-OCT-10 26-OCT-10
             2          1 26-OCT-10 27-OCT-10
             3          1 27-OCT-10 28-OCT-10
    SQL> insert into check_mte values (4, 2, trunc(sysdate), trunc(sysdate)+1);
    1 row created.
    SQL> insert into check_mte values (5, 2, trunc(sysdate), trunc(sysdate)+1);
    insert into check_mte values (5, 2, trunc(sysdate), trunc(sysdate)+1)
    ERROR at line 1:
    ORA-20500: Overlapping date range error.
    ORA-06512: at "CHECK_MTE", line 11
    ORA-04088: error during execution of trigger 'CHECK_MTE'Why is this not generating a Mutating Table Error?
    --=Chuck

    It's a multi-row update that causes the issue, not a single row update:
    SQL> insert into check_mte select * from check_mte;
    insert into check_mte select * from check_mte
    ERROR at line 1:
    ORA-04091: table CHECK_MTE is mutating, trigger/function may not see it
    ORA-06512: at "CHECK_MTE", line 4
    ORA-04088: error during execution of trigger CHECK_MTE'

  • Mutating Table workaround

    I have a trigger that fires when field A is updated.
    I would like to use field A to obtain a field in another table B
    and update the table that the trigger is on with the value of field B.
    I know that this would create a mutating table error, but I was wondering if there is any workaround. I have tried to use a statement level after update trigger and a row level before update trigger together on that table yet a continuous loop is created bc the statement level trigger updates the table which again fires the row level trigger.
    Are there any other workarounds for updating the same table that the trigger is firing on?

    Even if there is a foreign key from a to b, you can do something like this (a single row trigger) without causing a mutation issue:
    create or replace trigger a_trigger
    before insert or update on a
    for each row
    begin
      select name
        into :new.fk_name
        from b
       where pk = :new.fk;
    end;
    /

  • Mutating table and row state - this was unexpected

    So, I learned in a class about 3 years ago to expect the following
    SQL> create table p (pk number primary key);
    Table created.
    SQL> create table c (fk number references p(pk));
    Table created.
    SQL> create or replace trigger t_insrt
      2  before insert on p
      3  for each row
      4  begin
      5   insert into c values (:new.pk);
      6  end;
      7  /
    Trigger created.
    SQL> insert into p values (1);
    insert into p values (1)
    ERROR at line 1:
    ORA-02291: integrity constraint (FORBESC.SYS_C00169150) violated - parent key
    not found
    ORA-06512: at "FORBESC.T_INSRT", line 2
    ORA-04088: error during execution of trigger 'FORBESC.T_INSRT'and so it led me to think that replicating ON MODIFY PARENT - MODIFY CHILD functionality wouldn't work in a BEFORE ROW trigger, but it does
    SQL> drop trigger t_insrt;
    Trigger dropped.
    SQL> create or replace trigger p_updt
      2  before update on p
      3  for each row
      4  begin
      5   update c
      6   set fk = :new.pk
      7   where fk = :old.pk;
      8  end;
      9  /
    Trigger created.
    SQL> insert into p values (1);
    1 row created.
    SQL> insert into c values (1);
    1 row created.
    SQL> select * from c;
            FK
             1
    SQL> update p
      2  set pk = 2
      3  where pk = 1;
    1 row updated.
    SQL> select * from c;
            FK
             2Why would the first scenario fail while the second succeeds? The update seems prone to a parent record also not existing, at least not by the BEFORE ROW trigger.
    ---=Chuck

    < mutating table and row state >
    BTW, you don't seem to have run into the mutating table error though 2 other threads today are also about it. You have a constraint violation, a different thing entirely.
    I believe the second scenario works because you're neatly avoiding the error of the first. The error "ORA-02291: integrity constraint (FORBESC.SYS_C00169150) violated" means that on insert Oracle is looking up the value you're trying to insert, not finding it, and raising an error. With the before trigger you are taking the assigned value from the insert, updating the parent to it, so that on actual insert when the check happens the value is there due to the update.
    I'm not convinced this is a good idea because any on-the-fly approach to data entry needs to be examined carefully.

  • Deadlock error in trigger

    I created the following trigger and my requirement is updating the table with status column y, if the status column null values are less
    than particular number have to insert few records into the same table...here is the code..
    CREATE OR REPLACE TRIGGER WMOS_TEMP.insert_rec
    after UPDATE
    ON RSORT_TEMP
    REFERENCING NEW AS New OLD AS Old
    for each row
    WHEN (
    new.status = 'Y'
    DECLARE
    null_count pls_integer;
    pragma autonomous_transaction;
    begin
    select count(*) into null_count from rsort_temp where status is null;
    dbms_output.put_line ('null_count'||null_count);
    if(null_count < 2) then
    INSERT INTO rsort_temp
    SELECT 1,ddm.dock_door_brcd, ah.SHPMT_NBR, ch.case_nbr,NULL
    FROM case ch, asn ah, master ddm
    WHERE ch.ORIG_NBR = ah.SHPMT_NBR
    AND ch.ORIG_NBR = ddm.curr_nbr
    AND ah.stat_code >= 10
    AND ah.stat_code <= 30
    AND ch.stat_code = 0
    AND SUBSTR (ddm.brcd, 1, 2) = 'DR' and rownum < 10 ;
    commit;
    end if;
    END;
    but I got the following error:
    ORA-04091: table WMOS_TEMP.RECEIVEANDSORT_TEMP is mutating, trigger/function may not see it
    ORA-06512: at "WMOS_TEMP.INSERT_REC", line 4
    ORA-04088: error during execution of trigger 'WMOS_TEMP.INSERT_REC'
    Can you tell me how to code so that my requirement got done.
    Thanks,

    Hi,
    There's a lot wrong with this solution. You need to read about the mutating table error.
    First, in a row-level trigger you cannot reference your own trigger table in a select, insert, update or delete, because a change is still in progress, there's no consistent picture of the data there.
    Second, you can't commit transactions in a trigger, they're not an atomic part of a transaction.
    The "pragma autonomous transaction" was not created to circumvent those issues, so you need to rethink your logic. You either have to put that code in a stored procedure, likely the ideal option, or you could
    use the workaround with a package, and using statement level trigger with the row level to accomplish that logic (which Tom shows in his AskTom post below).
    Read these texts please. There's some database fundamentals you need to grasp before you think of the best solution for this problem.
    http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:9579487119866
    http://www.oracle.com/technology/oramag/oracle/08-sep/o58asktom.html

  • Create global temporary table in delete trigger

    Hi to all, I am triyng to create a global temporary table in trigger so i can hold all the deleted rows and do some stuff after the statement which uses the table that fires the trigger.
    In this way I am trying to avod mutating table error. but the following trigger gives error.
    create or replace
    TRIGGER TD_EKSINAVLAR
    FOR DELETE ON DERSSECIMI_EKSINAVLAR
    COMPOUND TRIGGER
    BEFORE STATEMENT IS
    BEGIN
    CREATE GLOBAL TEMPORARY TABLE DELETED_ROWS
    AS ( SELECT * FROM DERSSECIMI_EKSINAVLAR WHERE 1 = 2 )
    ON COMMIT DELETE ROWS;
    END BEFORE STATEMENT;
    BEFORE EACH ROW IS
    BEGIN
    NULL;
    END BEFORE EACH ROW;
    AFTER EACH ROW IS
    BEGIN
    NULL;
    END AFTER EACH ROW;
    AFTER STATEMENT IS
    BEGIN
    NULL;
    END AFTER STATEMENT;
    END TD_EKSINAVLAR;
    the error is
    Error(12,5): PLS-00103: Encountered the symbol "CREATE" when expecting one of the following: ( begin case declare exit for goto if loop mod null pragma raise return select update while with <an identifier> <a double-quoted delimited-identifier> <a bind variable> << continue close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge
    Please help me about the situation.
    Thanks in advance.
    Gokhan

    Karthick you are absolutly right
    Our main process is to migrate sql server 2000 database to oracle 11g and I am stuck with the triggers that reference to table that fires the trigger itself.
    Can you help me about how i can overcome mutating table errors using compund triggers? Espacially for the situation that one statement tries to update or delete multiple rows on a table.
    You can understand my logic from the above code. I want to hold all the affected rows in a table and in after statement body using a cursor on that table I want to do required changes on the table. How can I do that or how should I do ?
    regards.

Maybe you are looking for

  • Error 4000 please help!

    a couple months ago i could easily burn playlists from itunes. but now, the burn is cancelled every time. i even tried getting a different brand of cd's, but its not helping. here are the diagnostics: Microsoft Windows XP Professional Service Pack 2

  • Looping in XML publisher

    For this problem I went through following links Re: FOR loop in XML Publisher Re: How do you iterate through a string? Re: How can print blank rows for XML output report.. Based on the information I created one template as follow <?for-each:xdoxslt:f

  • On commit restriction on materialized view.

    Hello friends, I am creating one materialized view which needs to be refreshed on commit, While creating that MV, i am getting error stating "On commit is not allowed for that.." I have studied oracle documentations for the same. The only restriction

  • LIKE Query via JAC

    Hi, we are just thinking about how to access the Lite db via JAC or JDBC.For our application we need to replicate against a 8iServer db and therefore need a relational structure. So we won't have all the advantages of a object db. Anyway the access v

  • Oracle9iAS Reports Services

    I am using Oracle Application Server 9i Version9.0.3. I want to download Oracle9iAS Reports Services for this version. Where can i download it?