Home » SQL & PL/SQL » SQL & PL/SQL » what is mutating table?
what is mutating table? [message #39220] Thu, 27 June 2002 01:31 Go to next message
asheesh p. singh
Messages: 1
Registered: June 2002
Junior Member
what is mutating table?
Re: what is mutating table? [message #39221 is a reply to message #39220] Thu, 27 June 2002 02:02 Go to previous messageGo to next message
Mahesh Rajendran
Messages: 10707
Registered: March 2002
Location: oracleDocoVille
Senior Member
Account Moderator
this may help you
mutating tables
how to alter my trigger to circumvent mutating table error [message #39263 is a reply to message #39220] Mon, 01 July 2002 19:54 Go to previous messageGo to next message
Rozario Mariadassou
Messages: 12
Registered: March 2002
Junior Member
I want to build a generic procedure that can be used for maintianing a transaction log for audit / offline replication purposes. The procedure should be generic enough to be called by a trigger on any table . But I am running into the problem of mutating table. I am giving below the partial code for this generic procedure and the trigger on a sample table. Is there any other way I can achieve the same thing.
Best regards

CREATE PROCEDURE TEST
(IN_TABLE IN VARCHAR2,
IN_FLAG IN VARCHAR2,
IN_ROWID IN VARCHAR2) IS
SQLSTRING VARCHAR2(200);
V_TABLE VARCHAR2(100);
BEGIN
V_TABLE := 'TMP_' || IN_TABLE;
SQLSTRING := 'INSERT INTO ' || V_TABLE || ' (SELECT * FROM ' || IN_TABLE || ' WHERE ROWID = '''
|| IN_ROWID || ''')';
EXECUTE IMMEDIATE SQLSTRING;
END;

CREATE OR REPLACE TRIGGER TEST
AFTER INSERT OR DELETE OR UPDATE ON TMP FOR EACH ROW
DECLARE
V_FLAG VARCHAR2(1);
BEGIN
IF INSERTING THEN V_FLAG := 'I';
ELSIF UPDATING THEN V_FLAG := 'U';
ELSE V_FLAG := 'D';
END IF;
TEST('TMP',V_FLAG,:NEW.ROWID);
END ;

UPDATE TMP SET LOTNO='TESTING' WHERE LOTNO='401515';

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

ORA-06512: at "MYL.TEST", line 11

ORA-06512: at "MYL.TEST", line 8

ORA-04088: error during execution of trigger 'MYL.TEST'
Re: how to alter my trigger to circumvent mutating table error [message #39268 is a reply to message #39263] Tue, 02 July 2002 06:37 Go to previous messageGo to next message
Mahesh Rajendran
Messages: 10707
Registered: March 2002
Location: oracleDocoVille
Senior Member
Account Moderator
I am not very clear about your complete requirement.
Mutating trigger problem can be solved .
but from your code

SQLSTRING := 'INSERT INTO ' || V_TABLE || ' (SELECT * FROM ' || IN_TABLE || ' WHERE ROWID

you are trying to pass the table_name as parameter, which is very hard for implementation.
anyhow the following would be a workaround to audit a table using triggers. Idea is capture all the changes(insert,update,delete) on the table with the timestamp and insert them into another table. if this is not helping you, please let me know, we can look for some workaround.
SQL> ed
Wrote file afiedt.buf

  1  create table dept_audit
  2  (
  3  old_DEPTNO NUMBER(2),
  4  old_DNAME  VARCHAR2(14),
  5  old_LOC    VARCHAR2(13),
  6  new_DEPTNO NUMBER(2),
  7  New_DNAME  VARCHAR2(14),
  8  new_LOC    VARCHAR2(13),
  9* timestamp date) -- you can change the date into timestamp 
SQL> /

Table created.

SQL> get trig_audit
  1  -- you can change the sysdate into timestamp column
  2  CREATE OR REPLACE TRIGGER TRIG_AUDIT
  3  AFTER INSERT OR UPDATE OR DELETE ON DEPT
  4  FOR EACH ROW
  5  BEGIN
  6  IF INSERTING THEN
  7     insert into dept_audit values
  8     (NULL,NULL,NULL,:new.deptno,:new.dname,:new.loc,sysdate);
  9  END IF;
 10  IF UPDATING THEN
 11     insert into dept_audit values
 12     (:old.deptno,:old.dname,:old.loc,:new.deptno,:new.dname,:new.loc,sysdate);
 13  END IF;
 14  IF DELETING THEN
 15     insert into dept_audit values
 16     (:old.deptno,:old.dname,:old.loc,NULL,NULL,NULL,sysdate);
 17  END IF;
 18* end;
 19  /

Trigger created.

SQL> insert into dept values
  2  (50,'newdep','FLORIDa');

1 row created.

SQL> update dept set dname='recentdep' where deptno=50;

1 row updated.

SQL> delete from dept where deptno=50;

1 row deleted.

SQL>  select * from dept_audit;

OLD_DEPTNO OLD_DNAME      OLD_LOC       NEW_DEPTNO NEW_DNAME      NEW_LOC       TIMESTAMP
---------- -------------- ------------- ---------- -------------- ------------- --------------------
                                                50 newdep         FLORIDa       02-jul-2002 10:08:00
        50 newdep         FLORIDa               50 recentdep      FLORIDa       02-jul-2002 10:08:35
        50 recentdep      FLORIDa                                               02-jul-2002 10:08:46
Re: does not solve the problem [message #39277 is a reply to message #39263] Tue, 02 July 2002 18:59 Go to previous messageGo to next message
Rozario Mariadassou
Messages: 12
Registered: March 2002
Junior Member
This soln does not solve my problem. I hv almost 100 tables with an avg. of 20 fields per table. If I hv to code each trigger with :new.field name etc to make it self contained, it is going to involve a lot of effort. Passing table_name as a parameter is not the problem - it works. The problem is mutating table bcos I am selecting from the table on which the trigger is written. Ofcourse i could get the field name from TAB_COLUMNS and create the sqlstring (for the execute immediate) prefixing each field with :new etc through a cursor but i was wondering if there is a simpler way of doing it. Tks any way and let me know if u come up with another soln.
Re: what is mutating table? [message #40325 is a reply to message #39220] Fri, 27 September 2002 12:25 Go to previous message
Bart Sk
Messages: 1
Registered: September 2002
Junior Member
It's where a trigger tries to access the table that the trigger is on. For example, if I had a trigger on a table called TEMP, then in the trigger tried to query values from the TEMP table, it would error with a mutating table error.
Previous Topic: Optimize this query
Next Topic: column name
Goto Forum:
  


Current Time: Mon Apr 29 01:59:11 CDT 2024