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'

Similar Messages

  • Error "Mutating table" when execute a trigger

    Hi all,
    I'm a newbie in oracle. Recently i do some database migration from sql server 2005 to oracle 11g. Some of my table are using trigger which is not running in oracle. It has error "mutating table" when i'm trying to update some table. According to some information i got from the internet this can be solve by creating 1 packages and 3 trigger, but i found this article http://www.oracle.com/technetwork/issue-archive/2008/08-sep/o58asktom-101055.html which confuse me much. It says that the trigger is not allowed to be used for multiple user, meanwhile my application was for multiple user. What should i do then ?
    *sorry for my bad english                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

    Hi,
    Sorry for my late reply, below is one of my trigger that causes error. This trigger was automatically created when im doing the migration.
    create or replace
    TRIGGER "DBO_ORACLE_240312".tgrRwyPktUpd
    -- =============================================
    -- Author:          Debora Farah Rasul
    -- Create date: 09.02.2012
    -- Description:     Update Riwayat Pangkat untuk data SKCPNS/SKPNS
    -- =============================================
    AFTER UPDATE
    ON RiwayatPangkat
    FOR EACH ROW
    DECLARE
    v_temp NUMBER(1, 0) := 0;
    BEGIN
    IF NULL/*TODO:TRIGGER_NESTLEVEL()*/ > 2 THEN
    RETURN;
    END IF;
    --SQL Server BEGIN TRANSACTION;
    BEGIN
    SELECT 1 INTO v_temp
    FROM DUAL
    WHERE ( ( SELECT :NEW.isTrigger
    FROM DUAL ) = -1 );
    EXCEPTION
    WHEN OTHERS THEN
    NULL;
    END;
    IF v_temp = 1 THEN
    BEGIN
    MERGE INTO SKCPNS
    USING (SELECT :NEW.PegawaiID AS PegawaiID, :NEW.NoNota AS NoNota, :NEW.NoSK AS NoSK, :NEW.TglSK AS TglSK, :NEW.TMTPangkat AS TMTPangkat, :NEW.PangkatID AS PangkatID
    FROM dual) src
    ON (SKCPNS.PegawaiID = src.PegawaiID )
    WHEN MATCHED THEN UPDATE SET NoNota = src.NoNota,
    NoSK = src.NoSK,
    TglSK = src.TglSK,
    TMTCPNS = src.TMTPangkat,
    PangkatID = src.PangkatID;
    END;
    ELSE
    BEGIN
    SELECT 1 INTO v_temp
    FROM DUAL
    WHERE ( ( SELECT :NEW.isTrigger
    FROM DUAL ) = -2 );
    EXCEPTION
    WHEN OTHERS THEN
    NULL;
    END;
    IF v_temp = 1 THEN
    BEGIN
    MERGE INTO SKPNS
    USING (SELECT :NEW.PegawaiID AS PegawaiID, :NEW.NoSK AS NoSK, :NEW.TglSK AS TglSK, :NEW.TMTPangkat AS TMTPangkat, :NEW.PangkatID AS PangkatID
    FROM dual) src
    ON ( SKPNS.PegawaiID = src.PegawaiID )
    WHEN MATCHED THEN UPDATE SET NoSK = src.NoSK,
    TglSK = src.TglSK,
    TMTPNS = src.TMTPangkat,
    PangkatID = src.PangkatID;
    END;
    END IF;
    END IF;
    MERGE INTO RiwayatGaji
    USING (SELECT :NEW.PegawaiID AS PegawaiID, :NEW.NoUrut AS NoUrut, :NEW.NoSK AS NoSK, :NEW.TglSK AS TglSK, :NEW.TMTPangkat AS TMTPangkat, :NEW.PejabatPenetap AS PejabatPenetap, :NEW.MasaKerjaTh AS MasaKerjaTh, :NEW.MasaKerjaBl AS MasaKerjaBl, :NEW.PangkatID AS PangkatID, :NEW.JenisKP AS JenisKP
    FROM dual) src
    ON ( RiwayatGaji.PegawaiID = :NEW.PegawaiID
    AND RiwayatGaji.isTrigger = :NEW.NoUrut)
    WHEN MATCHED THEN UPDATE SET NoSK = src.NoSK,
    TglSK = src.TglSK,
    TMTSK = src.TMTPangkat,
    PejabatPenetap = src.PejabatPenetap,
    MasaKerjaTh = src.MasaKerjaTh,
    MasaKerjaBl = src.MasaKerjaBl,
    PangkatID = src.PangkatID,
    JenisKenaikan = src.JenisKP;
    END;
    *Btw thank u for the reply :)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

  • Mutating table exception & use of a table column in where clause

    Hello,
    I have a scenario in which I am getting a Mutating table exception in which I have a trigger using which I insert into a second table in case there is an insert in the first table or the one which is associated with the trigger .
    my trigger code has this line which is causing the Mutating table exception :
    BEGIN
    IF INSERTING THEN
    SELECT a,b INTO var_a,var_b
    FROM tableA,tableB,tableC
    WHERE tableC.c = :new:c
    The problem is the tableC reference in my where clause is causing a Mutating table exception , but I don't see any other way in which I can get rid of it cause I need to check if new:c values exists in the table or not , can anybody suggest how I can get rid of the tableC reference in my SQL statement yet be able to check for the value of :new:C in my statement ?

    Hopefully this demonstrates the problem , the bold portion or the where clause is where I am getting flummoxed , I need to be able to compare the new value to a column in table C but if I use tableC reference I get mutating table exception
    create or replace
    trigger myTrigger
    after insert or delete or update on TableC
    referencing old as old new as new
    for each row
    DECLARE val1 number; val2 CHAR(1);
    BEGIN
    IF INSERTING THEN
    SELECT tableA.val1,tableB.val2 INTO val1,val2
    FROM TableA tableA,TableB tableB
    WHERE :new.val1
    AND :new.val1 is not null
    AND tableA.val2 = :new.val2
    AND tableB.val3 = tableA.val3
    AND tableC.val4 = :new.val5
    INSERT INTO TableD (col1 ,
    col2,
    col3,
    col4,
    col5,
    col6,
    col7,
    col8,
    col9)
    VALUES(:new.val1,
    :new.val2,
    :new.val3,
    tableA.val1,
    tableB.val2,
    :new.val4,
    :new.val5,
    :new.val6,
    :new.val7);

  • Best way to deal with Mutating table exception with Row Level Triggers

    Hello,
    It seems to be that the best way to deal with Mutating Table exception(s) is to have to put all the trigger code in a package & use it in conjunction with a Statement level trigger .
    This sounds quite cumbersome to me . I wonder is there any alternative to dealing with Mutating table exceptions ?
    With Regards

    AskTom has a good article about this,
    http://asktom.oracle.com/tkyte/Mutate/index.html

  • 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 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.

  • 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,

  • Using a package for solving many mutating tables.....

    Hi,
    I need to solve more than one cases of mutating tables .. following the 'traditional' way described in:
    http://asktom.oracle.com/tkyte/Mutate/index.html
    For these cases , do you recommend me to use an individual package for each case ... or one to cover all cases (with different variables and PL/SQL tables... of course)....???
    Many thanks ,
    Simon

    No , I meant that there are cases on different
    tables....Then there is no other possibility but to create different packages.
    When you write "use api's"... can you give some more
    details....?????I mean to have a package to do all your dml in nice clean functions and procedures like procedure hire_employee, procedure fire_employee, function salary_including_commission and so on. Your procedures will include logic to validate all business rules. Then grant execute privileges on this package (api) to the users that should be able to work with employees and revoke all DML privileges on the table from anyone, even revoke the "CREATE SESSION" privilege from the schema owner when done installing to prevent direct access on the table.
    Now every DML action will be through your api and it's not possible to bypass constraint validation.
    Regards,
    Rob.

  • Autonomous Trigger / Mutating Table Problem

    We have a specific problem in one of our applications being developed where by the database needs to enforce a specific business requirement.
    We need to use a database trigger to enforce some data integrity which involves more than one table as such cannot use standard constraint. The integrity has to be maintained in the database as the DML statements may be coming from a Java application or PL/SQL code as such we need the logic all in one place.
    The problem being that within the trigger we need to examine the state of the table the trigger is associated with as well as one other table. Obviously using a trigger on a table that is being affected by DML statements causes the dreaded mutating table problem.
    One suggested solution to this was to make the trigger or the code the trigger called autonomous. This allows the trigger to execute by only showing the trigger the original state of the table before any of the DML statements have affected it.
    The problem is this seems to work for single row DML statements but not for multi row DML statements. In multi row the trigger only sees the original state of the table, not the state of the table plus the changes made by any other actions in the same DML statement.
    Below I have shown an example of what I'm seeing.
    I have grossly simplified the example code below to only refer to a single table and use stupidly simple logic
    I do realise i appear to be implementing uniqueness in my own PL/SQL code, this is purely for the example.
    CREATE TABLE mutate_test
    id INTEGER NOT NULL,
    value VARCHAR2(255) NOT NULL
    ALTER TABLE mutate_test ADD CONSTRAINT pk_mutate_test PRIMARY KEY(id);
    ALTER TABLE mutate_test ADD CONSTRAINT ck_mutate_test CHECK (value = UPPER(value));
    CREATE OR REPLACE FUNCTION duplicate_found(in_value IN mutate_test.value%TYPE) RETURN BOOLEAN IS
    PRAGMA AUTONOMOUS_TRANSACTION;
    v_value_found INTEGER;
    BEGIN
    SELECT COUNT(*)
    INTO v_value_found
    FROM mutate_test
    WHERE value = in_value;
    IF v_value_found > 0 THEN
    RETURN TRUE;
    ELSE
    RETURN FALSE;
    END IF;
    END;
    CREATE OR REPLACE TRIGGER tr_mutate_test BEFORE INSERT OR UPDATE ON mutate_test
    FOR EACH ROW
    BEGIN
    IF duplicate_found(:new.value) = TRUE THEN
    RAISE_APPLICATION_ERROR(-20000,'Duplicate value found');
    END IF;
    END;
    INSERT INTO mutate_test (id,value) VALUES (1,'CLIFF');
    INSERT INTO mutate_test (id,value) VALUES (2,'SULA');
    COMMIT;
    SELECT * FROM mutate_test;
    -- Should fail as row 1 already has a value of CLIFF
    INSERT INTO mutate_test (id,value) VALUES (3,'CLIFF');
    COMMIT;
    SELECT * FROM mutate_test;
    -- Should fail as row 1 is already set to CLIFF
    UPDATE mutate_test SET value = 'CLIFF' WHERE id = 2;
    COMMIT;
    SELECT * FROM mutate_test;
    UPDATE mutate_test SET value = 'CLIFFORD' WHERE id = 1;
    COMMIT;
    SELECT * FROM mutate_test;
    INSERT INTO mutate_test (id,value) VALUES (3,'RONNY');
    INSERT INTO mutate_test (id,value) VALUES (4,'TIM');
    INSERT INTO mutate_test (id,value) VALUES (5,'MONIQUE');
    COMMIT;
    SELECT * FROM mutate_test;
    -- Wanted result would be row 1 would be updated from CLIFFORD to CLIFF
    -- and the others raise errors, or all of them raise errors.
    UPDATE mutate_test SET value = 'CLIFF' WHERE id IN (1,3,4);
    COMMIT;
    SELECT * FROM mutate_test;

    This is all from a University application that deals with eLearning.
    Shell = Mapping from the system to an external eLearning application, ie: unique id of the Blackboard course shell, or WebBoard board.
    Term = Academic term
    Sector = University sector, ie: Higher Education, TAFE, etc..
    Resource = eLearning tool, ie: Blackboard, WebBoard, etc..
    Resource Level = Whether the resource is being offered at a Course or Program level
    Resource Mapping = Association of a resource to shell
    What we are trying to achieve is that shells cannot be used across sector boundaries.
    The real table structure is (grossly simplified again)
    CREATE TABLE sector (sector_pk INTEGER PRIMARY KEY);
    CREATE TABLE sector_pattern (sector_pk INTEGER REFERENCES sector(sector_pk), pattern CHAR(2) NOT NULL UNIQUE CHECK (pattern = UPPER(pattern)));
    CREATE TABLE term (term_pk INTEGER PRIMARY KEY, term CHAR(4) NOT NULL UNIQUE CHECK (term = UPPER(term)));
    CREATE TABLE resource_level (resource_level_pk INTEGER PRIMARY KEY, term_pk INTEGER REFERENCES term(term_pk));
    CREATE TABLE shell_detail (shell_detail_pk INTEGER PRIMARY KEY);
    CREATE TABLE resource_mapping (resource_mapping INTEGER PRIMARY KEY, resource_level_pk INTEGER REFERENCES resource_level(resource_level_pk), shell_detail_pk INTEGER REFERENCES shell_detail(shell_detail_pk));
    Based on the Ask Tom article linked I'd liked to use a MATERIALIZED VIEW on the following query
    SELECT DISTINCT rm.shell_detail_pk,sp.sector_pk
    FROM resource_mapping rm, resource_level rl, term t, sector_pattern sp
    WHERE rm.resource_level_pk = rl.resource_level_pk
    AND rl.term_pk = t.term_pk
    AND SUBSTR(t.term,3,2) = sp.pattern;
    Then apply a UNIQUE constraint on that VIEW.
    But I'm receiving a
    SQL Error: ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view
    I'm not sure how to create the MATERIALIZED VIEW LOG entries for the above VIEW.
    Any ideas anyone? ;)
    Need to do some more reading and research but as Tom says
    "I'm asking around about the future of "SQL" as far as enhancments go like that
    (will update when I get some feedback), but -- you are not limited to triggers
    (in fact, I would avoid triggers as it is virtually IMPOSSIBLE to implement
    cross row/cross object constraints with them!!!! at least correctly)"
    So I think i'll give up on the TRIGGER approach as it doesn't meet our requirements.

  • MUTATING TABLES(ORA-04091) ERROR

    HI ALL,
    i am trying to solve the above problem. I don't have much experience in pl/sql. I tell u the problem.
    I am trying to write trigger on transaction_master table before insert or update so that record can insert into tran_modify_log table. Because of the referential integrity i got the error ORA-04091. I COPIED THE FOLLOWING CODE. BUT ITS FOR ONLY ONE COLUMN.OTHER COLUMNS ARE HARD CODED. U can see this in 2nd trigger IN_TRANS_MOD_LOG. can any body help me to insert all the column values from transaction_master table to tran_modify_log table. If is there any easy way please let me know.
    with regards,
    vali
    CREATE OR REPLACE PACKAGE INSERT_TRANSACTION_MODIFY_LOG IS
    -- DEFINE A PL/SQL TABLE TYPE TO STORE THE ORDER_ID INFO
    TYPE INSERT_TRAN_MOD_LOG_TABLE IS TABLE OF TRANSACTION_MASTER.TRANSACTION_ID%TYPE
    INDEX BY BINARY_INTEGER;
    -- DECLARE VARIABLES FOR THE PL/SQL TABLE AND COUNTER
    INSERT_TRAN_MOD_LOG_TABLE_REC INSERT_TRAN_MOD_LOG_TABLE;
    INS_T_M_L_TAB_INDEX_NUM PLS_INTEGER:=0;
    END INSERT_TRANSACTION_MODIFY_LOG;
    CREATE OR REPLACE TRIGGER INS_TRANS_MOD_LOG BEFORE INSERT OR UPDATE ON TRANSACTION_MASTER FOR EACH ROW
    BEGIN
    --INCREMENT PL/SQL TABLE INDEX BEFORE INSERTING
    INSERT_TRANSACTION_MODIFY_LOG.INS_T_M_L_TAB_INDEX_NUM:=INSERT_TRANSACTION_MODIFY_LOG.INS_T_M_L_TAB_INDEX_NUM+1;
    --ADD THE TRANSACTION_ID TO THE PL/SQL TABLE
    INSERT_TRANSACTION_MODIFY_LOG.INSERT_TRAN_MOD_LOG_TABLE_REC(INSERT_TRANSACTION_MODIFY_LOG.INS_T_M_L_TAB_INDEX_NUM):
    =NVL(:OLD.TRANSACTION_ID,:NEW.TRANSACTION_ID);
    END INS_TRANS_MOD_LOG;
    CREATE OR REPLACE TRIGGER IN_TRANS_MOD_LOG BEFORE INSERT OR UPDATE ON TRANSACTION_MASTER
    BEGIN
    -- LOOP THROUGH THE PL/SQL, PERFORMING PROCESSING FOR EACH TRANSACTION
    FOR LV_TAB_INDEX_NUM IN 1..INSERT_TRANSACTION_MODIFY_LOG.INS_T_M_L_TAB_INDEX_NUM LOOP
    -- INSERT INITIAL TRANSACTION RECORD FOR EVERY TRANSACTION
    INSERT INTO TRAN_MODIFY_LOG(MODIFY_DATE,MODIFY_TIME,TRANSACTION_ID,USER_ID)
    VALUES('13/06/2002','13:30',INSERT_TRANSACTION_MODIFY_LOG.INSERT_TRAN_MOD_LOG_TABLE_REC(LV_TAB_INDEX_NUM),'MIKE');
    END LOOP;
    -- INITIALIZE PACKAGE VARIABLE COUNTER FOR SUBSEQUENT INSERTS
    INSERT_TRANSACTION_MODIFY_LOG.INS_T_M_L_TAB_INDEX_NUM:=0;
    END IN_TRANS_MOD_LOG;
    /

    sorry, my mistake, point 7-8 became:
    7) But if u now login with the sys dba account:
    connect sys/dbapass@database
    then drop student.trg_a and student.trg_b and then recreate both under the sys schema:
    CREATE OR REPLACE TRIGGER SYS.TRG_A
    AFTER INSERT OR DELETE ON STUDENT.P
    FOR EACH ROW
    begin
    if deleting then
    update STUDENT.Q set cnt=cnt-1 where id=2;
    else
    update STUDENT.Q set cnt=cnt+1 where id=2;
    end if;
    end;
    /--- cut point for trigger creation
    CREATE OR REPLACE TRIGGER SYS.TRG_B
    AFTER INSERT OR UPDATE ON STUDENT.Q
    FOR EACH ROW
    declare
    p number;
    maxr number;
    begin
    select sum(CNT) into p from STUDENT.Q where id=:new.id;
    select sum(MAX) into maxr from STUDENT.R where id=:new.id;
    dbms_output.put_line('P:'||p||', maxr:'||maxr);
    if (p<=maxr) then
    dbms_output.put_line('p<=maxr is true');
    else
    dbms_output.put_line('p<=maxr is false');
    end if;
    end;
    8) reconnect with ur working user account:
    example: connect student/password@database
    9) when re-doing inserts as point 6), the trigger sys.trg_b will fire without raising any ora-04091 error!!!!
    The trigger behave like if the mutating table limitation is not existing at all!!!
    does anyone know anything about this behavior?
    thank u very much
    sincerely

  • Updating a mutating table

    I have a after row trigger on a table which extracts data from another database through a database link. On insert/update of the row it updates the requisite tables in the database on which it is created.An exception is returned when if the rows are not inserted for any reason. This is to be updated in the triggering table column.Can you write a Stored Procedure to update the triggering table and avoid mutating table problem

    If you just want to update the triggering row with some specific value, then simply assign
    :new.columnname := 'some value';
    If you need to identify other rows in the same table, it's more complicated because the data is a state of flux. Potentially there are other triggers still to fire, in an unkown order, that could change the results of any query.

  • Mutating Table in 10.2.0.4

    After upgrading our environment from 10.2.0.3 to 10.2.0.4, the following trigger has started erroring when trying to insert data into the EMPLOYER_HOLDS table.
    CREATE OR REPLACE TRIGGER EMPHLD_BIR
    BEFORE INSERT
    ON EMPLOYER_HOLDS
    FOR EACH ROW
    BEGIN
    IF :NEW.emphld_no IS NULL
    THEN
    SELECT nvl(max(emphld_no), 0) + 1
    INTO :NEW.emphld_no
    FROM employer_holds
    WHERE prty_id = :NEW.prty_id
    AND empdtl_no = :NEW.empdtl_no;
    END IF;
    END;
    The error received is:
    ORA-04091: table UICONNECT.EMPLOYER_HOLDS is mutating, trigger/function may not see it
    ORA-06512: at "UICONNECT.EMPHLD_BIR", line 4
    ORA-04088: error during execution of trigger 'UICONNECT.EMPHLD_BIR'
    We have identified at least 145 other triggers in our environment that have this same issue.
    TWO QUESTIONS:
    1. Is there a workaround or a suggested solution to resolve this error?
    2. Can anyone confirm a comment I heard from another DBA that states the following: " This error actually occurred in 10.2.0.3 as well but a bug in that version of Oracle caused the error message to NOT be thrown, therefore giving no indication that the error occurred when in fact it may have"....can anyone shed some light on that statement? Is it accurate?
    Thanks in advance.
    Tony G.

    The main point is that you always had the error, even though you weren't able to see it, so you need to apply all the fixes, since your application is essentially not functioning the way you designed it.
    Do you have access to Metalink?
    If so, read up document ID 74859.1
    Oracle proposes a workaround, but only for referential integrity scenarios, which might be applicable to your circumstances
    >
    Scope and Application
    For users requiring the ability to cascade update, delete or insert whilst being able to maintain referential integrity between objects.
    ORA-4091 Mutating Table Explanation and Workarounds
    Overview
    The purpose of this paper is to illustrate to those customers who require one of the following functional capabilities whilst being able to maintain referential integrity among objects:
    * Cascade Update
    * Cascade Delete
    * Cascade Insert
    For cascade Update and Insert functions, using stored triggers and procedures will result in an ORA-04091 - "Table <table_name> is mutating" error.
    ORA-04091: "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.
    ORA-04091 is a very common error that occurs with triggers if triggers are not managed properly. A full understanding of triggers will help you avoid that error.
    A mutating table is a table that is currently being modified by an update, delete, or insert statement. You will encounter the ORA-04091 error if you have a row trigger that reads or modifies the mutating table. For example, if your trigger contains a select statement or an update statement referencing the table it is triggering off of you will receive the error.
    Another way that this error can occur is if the trigger has statements to change the primary, foreign or unique key columns of the table the trigger is triggering from.
    If you must have triggers on tables that have referential constraints, the workaround is to enforce the referential integrity through triggers as well.
    It must be stressed that this solution should ONLY be used to overcome DML restrictions imposed on triggers in order to maintain referential integrity. Whenever possible it is recommended that normal declarative integrity should be used to maintain foreign key integrity. Enforcing this integrity through stored triggers and procedures will have an effect on performance compared with declarative integrity.
    For this solution to work correctly there must be no declarative integrity constraints between objects to enforce the foreign key constraint. The basic principle behind this solution is to suppress the validation checks performed as a result of inserting or updating a foreign key in the CHILD table triggered by a cascade Update or Insert. These checks would normally verify the existence of the new foreign key value in the PARENT record (by SELECTING from the parent table). The suppression of this check is only carried out as a direct result of Cascade Update or Delete, as we can be confident that this new value for the foreign key in the CHILD record does exist (i.e. a result of it being inserted or updated in the PARENT table). In all other circumstances no suppression will take place (e.g. when changing the DEPTNO of an employee or when inserting a new employee).
    The following code illustrates how this is achieved for the cascade Update scenario, the code can easily be modified to add the other functionality and encapsulate it all within the same package. The EMP and DEPT table have been used, with the column EMP.DEPTNO in the EMP table referencing DEPT.DEPTNO in the DEPT table.

  • 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 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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

Maybe you are looking for

  • Location of UWL data in the database

    Hi, where exactly in the database does the data of UWLs get stored (table)? I guess I could figure it out by entering some data into a UWL and then searching in the database, but I have some infrastructural problems here. Thanks, Ingmar

  • As2 issue with loader

    I have been working on this for a minute and cannot seem to find out where I am going wrong been over the code several times and get the same result In my first layer I have 3 frames with unsing as2 Layer 1 frame 1 i have action  script movieSize = t

  • OLE objects & scaning in Acrobat 8.0

    Hello! In forums (May 3, 2007) I have read the question: " How to avoid dialogue of saving in a file before scanning in Acrobat 8"? Leonard Rosenthol has answered, that there is no way because now developers changed from "Scan & Save" to "Save & Scan

  • Media Encoder in settings mode only shows the lower half of screen

    All of a sudden, my Adobe Media Encoder CS4 is only showing the lower half of the screen in Settings mode. This is how it encodes from the .wmv file to .avi. and is therefore corrupting the file. Does anyone know why this has happened?

  • Remove Installer of Mountain Lion

    Hi, please need your help. Installing ML failed due to the fact of incompatibility with PGP on my system. How can I remove Mountain Lion Installer, since everytime I start the computer the system crashes, because it starts from the installer an dnot