Trigger is getting mutated
hello gurus ,
i have two tables MAIN_TB (main table),MAIN_HT (main table history)
MAIN_TB CONSIST OF
C_CODE VARCHAR2;
OCC_NO NUMBER;
can_cont char(1);
CONT_NO VARCHAR2;
LOG OB_LOG;
AND
MAIN_HT CONSIST OF
HT_OCC_NO NUMBER;
C_CODE VARCHAR2
OCC_NO NUMBER;
can_cont char(1);
CONT_NO VARCHAR2;
LOG OB_LOG;now my condition is this the HT table should get inserted whenever the occ_no in TB is updated when can_cont of TB table isnull and HT table should not be inserted when can_cont of TB is not null; but when i try this my trigger starts mutating how to stop that is there any other way that i cud use to develop my trigger
my trigger is
CREATE OR REPLACE TRIGGER main_tr
AFTER INSERT OR UPDATE OF occ_no
ON main_tb
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
ht_occ_no NUMBER := 0;
no_of_update NUMBER := 0;
BEGIN
BEGIN
SELECT MAX (nvl (ht_occ_no, 0))
INTO ht_occ_no
FROM main_ht
WHERE c_code = :NEW.c_code AND cont_no = :NEW.cont_no;
EXCEPTION
WHEN OTHERS
THEN
raise_application_error
(-20001,
'Error While Inserting Into MAIN_ht In MAIN_TR'
|| SQLERRM
END;
BEGIN
SELECT mtb.LOG.no_of_update
INTO no_of_update
FROM main_tb mtb
WHERE mtb.c_code = :OLD.c_code
AND mtb.cont_no = :OLD.cont_no
AND mtb.can_cont IS NULL;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
no_of_update := 0;
END;
IF UPDATING
THEN
IF no_of_update = 0
THEN
ht_occ_no := ht_occ_no + 1;
END IF;
END IF;
IF INSERTING
THEN
IF no_of_update = 0
THEN
RETURN;
END IF;
END IF;
BEGIN
INSERT INTO main_ht
(ht_occ_no, c_code, occ_no, can_cont, cont_no, LOG
VALUES (ht_occ_no, :OLD.c_code:OLD.occ_no, can_cont, cont_no, LOG
EXCEPTION
WHEN OTHERS
THEN
raise_application_error
(-20001,
'Error While Inserting Into MAIN_ht In MAIN_TR'
|| SQLERRM
END;
END main_tr;
/how do i stop trigger from mutating and how do i get my result with out using pragma autonomus transaction ?
thanks and Regards,
friend
Edited by: most wanted!!!! on Feb 5, 2012 10:49 PM
i ll check
actually my data should be like
1'st
Main TB
c_code cont_no occ_no can_cont log
c1 111 1 n 0
then
Main HT
ht_occ_no c_code cont_no occ_no can_cont log
should be empty
when
Main TBc_code cont_no occ_no can_cont log
c1 111 2 n 1
occ_no is updated
then
Main HT
ht_occ_no c_code cont_no occ_no can_cont log
1 c1 111 1 n 0
and after occ_no changes to 3 times for main tb
Main TB
c_code cont_no occ_no can_cont log
c1 111 5 n 1
then
then
Main HT
ht_occ_no c_code cont_no occ_no can_cont log
1 c1 111 1 n 0
1 c1 111 2 n 1
1 c1 111 3 n 2
1 c1 111 4 n 3
when can_cont is 'Y' then
Main TBc_code cont_no occ_no can_cont log
c1 111 5 y 1
no insert should take place in main_ht
then
Main HT
ht_occ_no c_code cont_no occ_no can_cont log
1 c1 111 1 n 0
1 c1 111 2 n 1
1 c1 111 3 n 2
1 c1 111 4 n 3
when
once again the same data is inserted in main tb then
Main TB
c_code cont_no occ_no can_cont log
c1 111 5 y 1
c1 111 1 y 0
then
Main HT
ht_occ_no c_code cont_no occ_no can_cont log
1 c1 111 1 n 0
1 c1 111 2 n 1
1 c1 111 3 n 2
1 c1 111 4 n 3
nothing should hapen first time
second time when updated then
Main TBc_code cont_no occ_no can_cont log
c1 111 5 y 1
c1 111 2 y 1
then
Main HT
ht_occ_no c_code cont_no occ_no can_cont log
1 c1 111 1 n 0
1 c1 111 2 n 1
1 c1 111 3 n 2
1 c1 111 4 n 3
2 c1 111 1 n 0
nothing should hapen first time
this is wat i want pheww..Edited by: most wanted!!!! on Feb 6, 2012 3:31 AM
Edited by: most wanted!!!! on Feb 6, 2012 3:44 AM
Similar Messages
-
[Solved] Unable to insert records, trigger is showing mutating error
Friends,
I created a procedure
===>>
SQL> CREATE OR REPLACE PROCEDURE PO_RECEIVINGS_ASSETS_TR_P
2 IS
3 CURSOR CUR_LAST_DAY_RCV IS
4 SELECT * FROM PO_RECEIVINGS_INSTANT_V WHERE TRANSACTION_ID = (SELECT MAX(TRANSACTION_ID) FROM PO_RECEIVINGS_INSTANT_V);
5 BEGIN
6 FOR REC_LAST_DAY_RCV IN CUR_LAST_DAY_RCV
7 LOOP
8 FOR i IN 1 .. REC_LAST_DAY_RCV.QUANTITY
9 LOOP
10 INSERT INTO ND_TEST VALUES(REC_LAST_DAY_RCV.TRANSACTION_ID, REC_LAST_DAY_RCV.CREATION_DATE, REC_LAST_DAY_RCV.QUANTITY,
11 REC_LAST_DAY_RCV.PO_LINE_ID);
12 END LOOP;
13 END LOOP;
14 END;
15 /
Procedure created.
<<===
then created a trigger to insert record in ND_TEST when a record is inserted in RCV_TRANSACTIONS_ND
===>>
SQL> CREATE OR REPLACE TRIGGER PO_RECEIVINGS_INTO_ASSETS_TR
2 AFTER INSERT ON RCV_TRANSACTIONS_ND
3 FOR EACH ROW
4 BEGIN
5 IF :NEW.TRANSACTION_TYPE = 'ACCEPT' THEN
6 PO_RECEIVINGS_ASSETS_TR_P;
7 END IF;
8 END;
9 /
Trigger created.
<<===
when I try to insert record in RCV_TRANSACTIONS_ND, I get below lines.
===>>
SQL> INSERT INTO RCV_TRANSACTIONS_ND (TRANSACTION_ID,LAST_UPDATE_DATE,LAST_UPDATED_BY,CREATION_DATE,
2 CREATED_BY,TRANSACTION_TYPE,TRANSACTION_DATE, QUANTITY, UNIT_OF_MEASURE, SHIPMENT_HEADER_ID,
3 SHIPMENT_LINE_ID,USER_ENTERED_FLAG, PO_HEADER_ID, PO_LINE_ID)
4 VALUES(1001001,SYSDATE,3572,SYSDATE,3572,'ACCEPT',SYSDATE,1,'Nos',199999,199099,'Y',133032,1679
29);
INSERT INTO RCV_TRANSACTIONS_ND (TRANSACTION_ID,LAST_UPDATE_DATE,LAST_UPDATED_BY,CREATION_DATE,
ERROR at line 1:
ORA-04091: table RCV_TRANSACTIONS_ND is mutating, trigger/function may not
see it
ORA-06512: at "PO_RECEIVINGS_ASSETS_TR_P", line 4
ORA-06512: at "PO_RECEIVINGS_ASSETS_TR_P", line 6
ORA-06512: at "PO_RECEIVINGS_INTO_ASSETS_TR", line 3
ORA-04088: error during execution of trigger
'PO_RECEIVINGS_INTO_ASSETS_TR'
<<===
Using Database 9i.Well, I tried to solve it and it worked.
SQL> CREATE OR REPLACE PROCEDURE PO_RECEIVINGS_ASSETS_TR_P(VAL1 IN NUMBER, VAL2 IN DATE, VAL3 IN NUMBER, VAL4 IN NUMBER)
2 IS
3 BEGIN
4 FOR i IN 1 .. VAL3
5 LOOP
6 INSERT INTO ND_TEST VALUES(VAL1, VAL2, VAL3, VAL4);
7 END LOOP;
8 END;
9 /
Procedure created.
===
SQL> CREATE OR REPLACE TRIGGER PO_RECEIVINGS_INTO_ASSETS_TR
2 AFTER INSERT ON RCV_TRANSACTIONS_ND
3 FOR EACH ROW
4 BEGIN
5 IF :NEW.TRANSACTION_TYPE = 'ACCEPT' THEN
6 PO_RECEIVINGS_ASSETS_TR_P(:NEW.TRANSACTION_ID, :NEW.CREATION_DATE, :NEW.QUANTITY, :NEW.PO_LINE_ID);
7 END IF;
8 END;
9 /
Trigger created.
===
SQL> INSERT INTO RCV_TRANSACTIONS_ND (TRANSACTION_ID,LAST_UPDATE_DATE,LAST_UPDATED_BY,CREATION_DATE,
2 CREATED_BY,TRANSACTION_TYPE,TRANSACTION_DATE, QUANTITY, UNIT_OF_MEASURE, SHIPMENT_HEADER_ID,
3 SHIPMENT_LINE_ID,USER_ENTERED_FLAG, PO_HEADER_ID, PO_LINE_ID)
4 VALUES(1001001,SYSDATE,3572,SYSDATE,3572,'ACCEPT',SYSDATE,1,'Nos',199999,199099,'Y',133032,1679
29);
1 row created.
===
Thanks everyone -
LOGOFF TRIGGER for getting Ip address info,etc
Hi Friends
I am thankful to you that you give such a useful information about my query.
Now I am using the following logon trigger in order to get the required information:
CREATE OR REPLACE TRIGGER trg_session_info
AFTER LOGON ON DATABASE
DECLARE
session_ids VARCHAR2(30);
work_stations VARCHAR2(30);
host_names VARCHAR2(30);
database_servers VARCHAR2(30);
db_domains VARCHAR2(30);
auth_types VARCHAR2(30);
ip_addrs VARCHAR2(30);
network_protocols VARCHAR2(30);
BEGIN
SELECT sys_context ('USERENV', 'SESSIONID') INTO session_ids
FROM dual;
SELECT SYS_CONTEXT('USERENV','OS_USER') INTO work_stations
FROM dual;
SELECT SYS_CONTEXT('USERENV','HOST') INTO host_names
FROM dual;
SELECT SYS_CONTEXT('USERENV','DB_NAME') INTO database_servers
FROM dual;
SELECT SYS_CONTEXT('USERENV','DB_DOMAIN') INTO db_domains
FROM dual;
SELECT sys_context ('USERENV', 'AUTHENTICATION_TYPE')INTO auth_types
FROM dual;
SELECT sys_context ('USERENV', 'IP_ADDRESS') INTO ip_addrs
FROM dual;
SELECT SYS_CONTEXT('USERENV','NETWORK_PROTOCOL') INTO network_protocols
FROM dual;
INSERT INTO session_info(session_id,client_name,logon_date,
work_station,host_name,database_server,db_domain,auth_type,ip_address,network_protocol)
VALUES (session_ids,user,sysdate,work_stations ,host_names ,database_servers,db_domains,
auth_types,ip_addrs, network_protocols);
commit;
END;
I also use the LOGOFF trigger in order to get rid of the session information when they logoff.
But it is not useful if the session terminated abnormally,because the session information cant delete from the session_info table.
Is there another approach in order to delete the session information from the table session_info, when they termniated abnormally?
Following is the LOGOFF TRIGGER which I am using now:
CREATE OR REPLACE TRIGGER logoff_session
BEFORE LOGOFF ON DATABASE
DECLARE
session_idss VARCHAR2(30);
BEGIN
SELECT sys_context ('USERENV', 'SESSIONID') INTO session_idss
FROM dual;
DELETE from session_info where session_id=session_idss;
commit;
commit;
END;
Could you please give your comment on the above problem that how to delete the session information from the table when it terminated abnormally.
In addition,I like to inform you that I am using Oraexcel for getting the information available on it.
I am using the following query in order to populate an excel sheet:
select SESSION_ID,CLIENT_NAME,to_char(logon_date, 'DD/MM/YY HH24:MI:SS')LOGON_TIME,
WORK_STATION,HOST_NAME,DATABASE_SERVER,DB_DOMAIN, AUTH_TYPE,IP_ADDRESS,NETWORK_PROTOCOL
from session_info;
So my table session_info populates the required information into an Excel sheet,whenevere clients logon to database.
But now I want that this information ,which is available on Oraexcel sheet,would be showing a Graphic-visualization of the Network from an Oracle perspective.
The graphical visualization will show the Database server and the connected clients and below the clients show the active sessions.
Could someone please give me idea how should I do that?
THANKS
WITH BEST REGARDS
BILALYou really should consider using Auditing instead of the trigger based solution.
Its much less work to implement and much more reliable
With your new requirements, it's just
set AUDIT_TRAIL = TRUE in the init.ora
restart the database and switch Auditing on:
SQL>AUDIT SESSION;
Fore some more information see
Auditing Connections and Disconnections
http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96521/audit.htm#9471 -
Write trigger without gerating Mutation...
Hi all,
there are 2 tables, a master and detail, one field in master constains sum data of amount field in details, i want to write a trigger to update the master sum field whenever any record is added/update or deleted in the detail. i think normal way of writing may raise mutation...so how to avioid...any suggestions. ?
regards
KrisBelow is an example of Mutating Trigger Fix With Autonomous Transaction, also for other implementations you may check this post - http://tonguc.oracleturk.org/index.php/2006/06/12/dealing-with-mutating-table-errors-dealing-with-mutating-table-errors-a-solution-based-on-collections/
SQL> CREATE TABLE t1 (x int);
Table created.
SQL> CREATE TABLE t2 (x int);
Table created.
SQL> INSERT INTO t1 VALUES (1);
1 row created.
SQL> SELECT * FROM t1;
X
1
SQL> SELECT * FROM t2;
no rows selected
SQL> CREATE OR REPLACE TRIGGER t_trigger
2 AFTER INSERT
3 ON t1
4 FOR EACH ROW
5
6 DECLARE
7 i PLS_INTEGER;
8 BEGIN
9 SELECT COUNT(*)
10 INTO i
11 FROM t1;
12
13 INSERT INTO t2
14 VALUES
15 (i);
16 END;
17 /
Trigger created.
SQL> INSERT INTO t1 VALUES (1);
INSERT INTO t1 VALUES (1)
ERROR at line 1:
ORA-04091: table HR.T1 is mutating, trigger/function may not see it
ORA-06512: at “HR.T_TRIGGER”, line 4
ORA-04088: error during execution of trigger ‘HR.T_TRIGGER’
SQL> SELECT COUNT(*) FROM t1;
COUNT(*)
1
SQL> SELECT COUNT(*) FROM t2;
COUNT(*)
0
SQL> CREATE OR REPLACE TRIGGER t_trigger
2 AFTER INSERT ON t1 FOR EACH ROW
3
4 DECLARE
5 PRAGMA AUTONOMOUS_TRANSACTION;
6 i PLS_INTEGER;
7 BEGIN
8 SELECT COUNT(*)
9 INTO i
10 FROM t1;
11
12 INSERT INTO t2
13 VALUES
14 (i);
15 COMMIT;
16 END;
17 /
Trigger created.
SQL> INSERT INTO t1 VALUES (1);
1 row created.
SQL> SELECT COUNT(*) FROM t1;
COUNT(*)
2
SQL> SELECT COUNT(*) FROM t2;
COUNT(*)
1
Best regards. -
When Validate Trigger is getting executed when Execute_query
i have a data block in which i have 2 text item. i have defined when validate item.
when the form is starting up i have given execute_query. before fetching the values my when validate item is getting executed. i dont want to do this. can one help me out in this caseHi,
Can you pls. check any initial value is given or not? Otherwise for quick solution you can declare a parameter upon which when-validate will validate the value. You can change value before and after 'EXECUTE_QUERY' statement. This is not a good idea. -
Process trigger lookups getting cleared on opening GTC
Hi,
We have an issue with process trigger lookup, whenever we open the Generic connector for some configuration changes it is clearing the process trigger lookup. Is there any fix or workarounds?
Thanks,Hi,
Its known issue with GTC. To overcome this issue, Oracle has published one doc in support site. That documents has all the steps to overcome this issue.
That document tells that you need to create one lookup corresponding to each custom UDF.
HTH,
~J -
Tracking when a Trigger is getting fired
Hi All,
Is there any way through which we can identify that any changes made in db is because of triggers.
How does oracle track triggers event.
thanks,>
I'm probably missing something but how would you use FGA to determine whether a DML operation was
the result of a trigger or not? You can obviously audit who did what. But I'm not seeing an obvious way to
determine that DML was fired by a trigger or by something else...Sorry, I should have explained myself better. Frequently (but not always) this sort of question revolves around
some sort of auditing issue - many posts ask this in the hope of avoiding paying for the auditing option. I was
merely suggesting that IF this was the case, you're far better off going with Oracle's solution - already
debugged, more "testers" - i.e. users. I've had more than one boss who went with "home brew" solutions
to the detriment of the business (not to mention the employees' sanity ;) ) - but, as I said above, I should have
been clearer in explaining the exact context of my post.
HTH,
Paul...
Justin -
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
DivyaThis 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 -
Hi all,
I have a trigger shown below is gives me the mutating error.
The error is to do with the select from the payments table (which it does not allow cos of the mutating effect).
Can anyone give me some ideas on how I can resolve this?
Thank you very much
create or replace
TRIGGER CHECK_INVOICE_PAID_IN_FULL AFTER
UPDATE OF "PAYMENT_STATUS" ON "PAYMENTS" FOR EACH ROW
DECLARE
-- check if all the payments for that invoice have been received (completed)
-- if they are complete then sum all the payments for that invoice and compare to gross value on invoices
v_invoice_amount NUMBER;
v_gross_amount NUMBER;
thisproc CONSTANT VARCHAR2(80) := 'trap_errmesg for mco_transfer_status';
v_value VARCHAR2(150);
BEGIN
-- Changed as requested by nicola on 12/09/05 IF :NEW.PAYMENT_COMPLETE is not null
IF :NEW.PAYMENT_STATUS='C' AND :NEW.PAYMENT_STATUS <> :OLD.PAYMENT_STATUS
THEN
-- We will sum all the payments for that invoice that have a value in payment_complete
SELECT NVL(SUM(amount),0) INTO v_invoice_amount FROM payments WHERE payment_complete IS NOT NULL AND invoice_id=:NEW.INVOICE_ID;
-- We will also get the gross amount for the invoice to compare to the sum of the payments
SELECT NVL(gross,0) INTO v_gross_amount FROM invoices WHERE
invoice_id = :NEW.INVOICE_ID ;
END IF;
IF v_invoice_amount = v_gross_amount
THEN
UPDATE invoices SET paid_date=SYSDATE;
END IF;
END CHECK_INVOICE_PAID_IN_FULL;
/Hi Anwar,
Thanks for this.
Can you please help me out here
I did the bit with creating a temporay table to hold the invoice_ids and then created a procedure that will be fired by the trigger, however because of the clause
IF :NEW.PAYMENT_STATUS='C' AND :NEW.PAYMENT_STATUS <> :OLD.PAYMENT_STATUS
I cant use a statement level trigger for this procedure and when i use the row level trigger i get the mutating error.
here is what i have got so far.
A temporary table which holds the invoice_ids (this is called payments_temp)
I then created a trigger as below which populates this temp table
TRIGGER insert_payments_temp BEFORE
UPDATE OF "PAYMENT_STATUS" ON "PAYMENTS" FOR EACH ROW
DECLARE
-- check if all the payments for that invoice have been received (completed)
-- if they are complete then sum all the payments for that invoice and compare to gross value on invoices
v_invoice_amount NUMBER;
v_gross_amount NUMBER;
thisproc CONSTANT VARCHAR2(80) := 'trap_errmesg for mco_transfer_status';
v_value VARCHAR2(150);
BEGIN
INSERT INTO payments_temp
VALUES (:NEW.invoice_id);
END insert_payments_temp;
Then I created a procedure below which will do the update
PROCEDURE "CHECK_INVOICE_PAID_IN_FULL_PRO" IS
-- check if all the payments for that invoice have been received (completed)
-- if they are complete then sum all the payments for that invoice and compare to gross value on invoices
v_invoice_amount NUMBER(20);
v_gross_amount NUMBER;
thisproc CONSTANT VARCHAR2(80) := 'trap_errmesg for mco_transfer_status';
v_value VARCHAR2(150);
BEGIN
-- We will sum all the payments for that invoice that have a value in payment_complete
--select sum(amount) into v_invoice_amount from payments where payment_complete is not null and invoice_id=:NEW.INVOICE_ID;
FOR x IN (SELECT invoice_id FROM payments_temp) LOOP
SELECT NVL(SUM(amount),0) INTO v_invoice_amount FROM payments
WHERE payment_complete IS NOT NULL AND invoice_id=X.INVOICE_ID;
SELECT NVL(gross,0) INTO v_gross_amount FROM INVOICES WHERE
invoice_id = X.INVOICE_ID ;
END LOOP;
-- We will also get the gross amount for the invoice to compare to the sum of the payments
IF v_invoice_amount = v_gross_amount
THEN
UPDATE INVOICES SET paid_date=SYSDATE;
COMMIT;
END IF;
END CHECK_INVOICE_PAID_IN_FULL_PRO;
Then finally the update trigger itself below
TRIGGER "NICKC"."CHECK_INVOICE_PAID_IN_FULL" AFTER
UPDATE OF "PAYMENT_STATUS" ON "NICKC"."PAYMENTS" FOR EACH ROW
DECLARE
-- check if all the payments for that invoice have been received (completed)
-- if they are complete then sum all the payments for that invoice and compare to gross value on invoices
v_invoice_amount NUMBER;
v_gross_amount NUMBER;
thisproc CONSTANT VARCHAR2(80) := 'trap_errmesg for mco_transfer_status';
v_value VARCHAR2(150);
BEGIN
-- Changed as requested by nicola on 12/09/05 IF :NEW.PAYMENT_COMPLETE is not null
IF :NEW.PAYMENT_STATUS='C' AND :NEW.PAYMENT_STATUS <> :OLD.PAYMENT_STATUS
THEN
CHECK_INVOICE_PAID_IN_FULL_PRO;
END IF;
END CHECK_INVOICE_PAID_IN_FULL;
However i still get the mutating error message and when i try to create a statemtnet level trigger i get the message say cannot use :NEW and :OLD values here.
Please help -
Help Required for date display & mutating trigger
Hai all..
I need clarification for 2 problems.
Problem 1
Is there a possibility to display the values with a date range.
I mean if there is no data for a particular date within the given range. it should display some null value.
Eg.
table name : sample
Sno Date1 Name desgn
1 1-may-2004 xyz engr
1 3-may-2004 xyz engr-1
1 4-may-2004 xyz engr-2
The query is
select * from sample where date1 between '01-may-2004' and '04-may-2004'.
The result of query will be
Sno Date1 Name desgn
1 1-may-2004 xyz engr
1 3-may-2004 xyz engr-1
1 4-may-2004 xyz engr-2
But i need the result to be displayed as
Sno Date1 Name desgn
1 1-may-2004 xyz engr
nil 2-may-2004 nil nil
1 3-may-2004 xyz engr-1
1 4-may-2004 xyz engr-2
Pls let me know how to achieve this.
Problem 2:
While i am updating a value using a trigger.
I am getting "mutating" error.
Is there a possibility to avoid the mutation.
The two triggers i am using is
Trigger 1
CREATE OR REPLACE TRIGGER TRIG_DURATION_UPDATED
AFTER UPDATE ON
TIMESHEET_DATA
FOR EACH ROW
DECLARE
ID_COUNT DATE;
A date;
NN NUMBER;
AA NUMBER;
NN1 NUMBER;
BEGIN
b_dur :=0;
IF UPDATING('PROGRESS') THEN
SELECT COUNT(1) INTO AA FROM TIMESHEET_DATA_PAUSE WHERE DATA_sNO = :OLD.DATA_SNO AND EMP_ID = :OLD.EMP_ID AND
ACNUM = :OLD.ACNUM AND DURATION IS NULL;
IF AA > 0 THEN
SELECT to_date(START_TIME,'DD-MON-YYYY HH:MI AM') into a FROM TIMESHEET_dATA_PAUSE WHERE
EMP_ID = :NEW.EMP_ID AND ACNUM = :new.acnum AND DATA_SNO = :new.data_sno AND pause_TIME IS NULL
AND DURATION IS NULL;
select to_date(sysdate,'DD-MON-YYYY HH:MI AM') into id_count from dual;
SELECT A - ID_COUNT INTO NN FROM DUAL;
SELECT round(TRUNC(NN*24),2) INTO NN1 FROM DUAL;
UPDATE TIMESHEET_dATA_PAUSE SET DURATION = NN1,PAUSE_TIME = SYSDATE WHERE
EMP_ID = :NEW.EMP_ID AND ACNUM = :new.acnum
AND DATA_SNO = :new.data_sno AND pause_TIME IS NULL AND DURATION IS NULL;
END IF;
END IF;
END;
Trigger 2
CREATE OR REPLACE TRIGGER TRIG_DURATION_UPDATED_PAUSE
AFTER UPDATE ON
TIMESHEET_DATA_PAUSE
FOR EACH ROW
DECLARE
ID_COUNT DATE;
A_COUNT NUMBER(10);
A date;
NN NUMBER;
AA NUMBER;
NN1 NUMBER(10,2);
BEGIN
IF UPDATING('DURATION') THEN
SELECT COUNT(1) INTO A_COUNT FROM TIMESHEET_DATA WHERE DATA_sNO = :new.data_sno AND EMP_ID =:new.EMP_ID
AND ACNUM = 'ACNUM' AND DURATION IS NULL;
IF A_COUNT >0 THEN
SELECT NVL(SUM(DURATION),0) INTO NN1 FROM TIMESHEET_DATA_PAUSE WHERE DATA_sNO = :new.data_sno AND EMP_ID =:new.EMP_ID AND ACNUM = :NEW.ACNUM;
UPDATE TIMESHEET_DATA SET DURATION = NN1 WHERE DATA_sNO = :new.data_sno AND EMP_ID =:new.EMP_ID AND ACNUM = :NEW.ACNUM AND DURATION IS NULL;
END IF;
END IF;
EXCEPTION WHEN DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE ('CANNOT INSERT');
END;
Pls let me know the solutions for the two..
Thanks in Advance
Gaya3In future please start two threads when you have two questions to ask. Othewise it makes things difficult to follow and may well lead to some of your questions not getting an answer. Unlike some other sites there is no limit to the number of posts we can have :)
To answer your first question:
If you have Oracle9i you can do this using a PIPELINED function to act as a pivot table (in earlier versions you will have to have a table of some description - ALL_OBJECTS will do in a pinch).
CREATE OR REPLACE TYPE t_dates AS TABLE OF DATE
CREATE OR REPLACE FUNCTION f_dates
(st IN DATE, cnt IN INTEGER) RETURN t_dates
PIPELINED
AS
dd date;
BEGIN
FOR a IN 1..cnt LOOP
SELECT st + (a-1)
INTO dd
FROM dual;
PIPE ROW (dd);
END LOOP;
RETURN;
END f_dates;
/So, given this data...
SQL> select * from t57
2 /
COL1 COL2
3 05-MAY-04
4 06-MAY-04
5 07-MAY-04
6 12-MAY-04
8 15-MAY-04
5 rows selected.
SQL>...we can run this query...
SQL> SELECT nvl(to_char(t.col1), 'Nil'), dd.ndate
2 FROM t57 t
3 , ( select column_value AS ndate from table(cast(f_dates(trunc(SYSDATE), 11) AS t_dates))) dd
4 WHERE trunc(dd.ndate) = trunc(t.col2(+))
5 /
NVL(TO_CHAR(T.COL1),'NIL') NDATE
3 05-MAY-04
4 06-MAY-04
5 07-MAY-04
Nil 08-MAY-04
Nil 09-MAY-04
Nil 10-MAY-04
Nil 11-MAY-04
6 12-MAY-04
Nil 13-MAY-04
Nil 14-MAY-04
8 15-MAY-04
11 rows selected.
SQL> Obviously, you will want to tidy up the function to suit your needs.
Cheers, APC -
ORA-04091: table is mutating, trigger/function
I am using oracle 11g R2 - 11.2.0.1
I have following function to fetch the ID from name supplied
create or replace
FUNCTION get_group_id
(p_groupname IN group_list.groupname%TYPE)
RETURN group_list.group_id%TYPE
AS
v_group_id group_list.group_id%TYPE;
BEGIN
SELECT group_list.group_id
INTO v_group_id
FROM group_list
WHERE group_list.groupname = p_groupname;
RETURN v_group_id;
END get_group_id;
and I am doing simple update command to the table, but its giving me ORA-04091 error. Any help is appreciated
update GROUP_LIST set MGR_GROUP_ID = get_group_id('manager1') where group_id = get_group_id('employee51');
Error which I am getting is -
Error report:
SQL Error: ORA-04091: table is mutating, trigger/function may not see it
ORA-06512: at "GET_GROUP_ID", line 7
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.>
and I am doing simple update command to the table, but its giving me ORA-04091 error. Any help is appreciated
update GROUP_LIST set MGR_GROUP_ID = get_group_id('manager1') where group_id = get_group_id('employee51');
Error which I am getting is -
Error report:
SQL Error: ORA-04091: table is mutating, trigger/function may not see it
>
And do you have a trigger on the GROUP_LIST table that calls you function that queries the GROUP_LIST table?
The solution is simple: DON'T DO THAT!
See Trigger Restrictions on Mutating Tables in the SQL Language doc
http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/triggers.htm#g1699708
Trigger Restrictions on 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 run-time error occurs, the effects of the trigger body and triggering statement are rolled back, and control is returned to the user or application. (You can use compound triggers to avoid the mutating-table error. For more information, see Using Compound Triggers to Avoid Mutating-Table Error.)
Consider the following trigger:
CREATE OR REPLACE TRIGGER Emp_count
. . . -
Mutating error in my trigger code
Hi,
Could anyone please help me out to fix the mutating error:
I have 2 tables z_errorpayment and z_errorcorrected.
If the status=2 in z_errorpayment table then a row has to be inserted in z_errorcorrected table and the same row has to be deleted from the 1st table i.e z_errorpayment.As it is retriving from the same table and deleting the same table am getting mutating error.
Below is the code.
CREATE OR REPLACE TRIGGER row_trigger
AFTER UPDATE
ON z_errorpayment
FOR EACH ROW
WHEN (NEW.status = 2)
BEGIN
INSERT INTO z_errorcorrected
(mtnl_error_payment_id, file_name, entry_date,
centre_code, service_code, instrument_flag,
instrument_no, subs_no, instrument_dt,
payment_mode, payment_dt, surchrg,
telephone_no, cheque_number, cheque_dt,
bank_code, pay_amount, receipt_no,
terminal_id, crtn_by, crtn_dt, remarks,
status, external_trans_id, transfer_date,
gl_uploaded_ind_code, task_queue_id,
user_name, old_payment_id, new_payment_id,
payment_type
VALUES (:NEW.mtnl_error_payment_id, :NEW.file_name, :NEW.entry_date,
:NEW.centre_code, :NEW.service_code, :NEW.instrument_flag,
:NEW.instrument_no, :NEW.subs_no, :NEW.instrument_dt,
:NEW.payment_mode, :NEW.payment_dt, :NEW.surchrg,
:NEW.telephone_no, :NEW.cheque_number, :NEW.cheque_dt,
:NEW.bank_code, :NEW.pay_amount, :NEW.receipt_no,
:NEW.terminal_id, :NEW.crtn_by, :NEW.crtn_dt, :NEW.remarks,
:NEW.status, :NEW.external_trans_id, :NEW.transfer_date,
:NEW.gl_uploaded_ind_code, :NEW.task_queue_id,
:NEW.user_name, :NEW.old_payment_id, :NEW.new_payment_id,
:NEW.payment_type
DELETE FROM z_errorpayment
WHERE new_payment_id = :NEW.new_payment_id;
END;
so I thought of using a view inorder to get rid of the mutating error.
But donno how to code it.
could anyone please help me out.
Regards,
RupaBy using a view i wrote the below code:
CREATE OR REPLACE TRIGGER row_trigger
INSTEAD OF UPDATE
ON Z_ErrorView
FOR EACH ROW
DECLARE
X INTEGER;
BEGIN
SELECT STATUS into X FROM z_errorpayment WHERE new_payment_id = :NEW.new_payment_id;
IF X=2 THEN
INSERT INTO z_errorcorrected
(mtnl_error_payment_id, file_name, entry_date,
centre_code, service_code, instrument_flag,
instrument_no, subs_no, instrument_dt,
payment_mode, payment_dt, surchrg,
telephone_no, cheque_number, cheque_dt,
bank_code, pay_amount, receipt_no,
terminal_id, crtn_by, crtn_dt, remarks,
status, external_trans_id, transfer_date,
gl_uploaded_ind_code, task_queue_id,
user_name, old_payment_id, new_payment_id,
payment_type
VALUES (:NEW.mtnl_error_payment_id, :NEW.file_name, :NEW.entry_date,
:NEW.centre_code, :NEW.service_code, :NEW.instrument_flag,
:NEW.instrument_no, :NEW.subs_no, :NEW.instrument_dt,
:NEW.payment_mode, :NEW.payment_dt, :NEW.surchrg,
:NEW.telephone_no, :NEW.cheque_number, :NEW.cheque_dt,
:NEW.bank_code, :NEW.pay_amount, :NEW.receipt_no,
:NEW.terminal_id, :NEW.crtn_by, :NEW.crtn_dt, :NEW.remarks,
:NEW.status, :NEW.external_trans_id, :NEW.transfer_date,
:NEW.gl_uploaded_ind_code, :NEW.task_queue_id,
:NEW.user_name, :NEW.old_payment_id, :NEW.new_payment_id,
:NEW.payment_type
END IF;
DELETE FROM z_errorpayment
WHERE new_payment_id = :NEW.new_payment_id;
END; -
hi guys,
Need you mastery about mutating table.
how can I rewrite sample trigger below, in compound trigger to avoid mutating table?
oracle version:
Oracle Database 11g Release 11.1.0.7.0 - 64bit Production
PL/SQL Release 11.1.0.7.0 - Production
"CORE 11.1.0.7.0 Production"
TNS for Linux: Version 11.1.0.7.0 - Production
NLSRTL Version 11.1.0.7.0 - Production
Table1 has (col1,col2,col3,col4)
Table2 has(col1,col2,col3,col4,col5)
Table3 has(col1,col2,col3,col4,col5)
Table4 has(col1,col2,col3,col4)
Create or replace trigger tble1_after_insert
after insert on tabl1
referencing old as old new as new
for each row
Begin
Insert into table4
( select table1.col1,table1.col2,table2.col3,table3.col4
where table1.col1 = table2.col1 (+)
and table2.col3 = table3.col3(+)
and table.col1 = :new.table1.col1)
End;
Mutating problem will occur on table1, that's why I need to convert the script on compound trigger.
If there will be a better way rather than compound trigger kindly share your ideas.
thank you in advancezacky wrote:
Hi Guys,
Thanks for the references.
@ Paul thanks for the idea, follow up question I have another condition on where clause; below is the actual script
(part of insert into Table select statement)
SELECT O.order_id,
COALESCE (dl.isbn, cl.isbn, ol.product_id) eisbn,
CO.organisation_id,
O.order_status,
O.order_type,
CL.collection_id,
DECODE(cl.concurrency_flag, 0, 0, 1, cb.concurrency_limit) access_limit
FROM ebook_order O,
ebook_isbn_data_load DL,
ebook_order_line OL,
ebook_collection_list CL,
ebook_concurrency_band CB,
consortium_organisation CO,
ebook_order O
WHERE o.order_id = ol.order_id
AND ol.product_id = cl.collection_id(+)
AND cl.isbn = dl.ean13_of_set(+)
AND o.concurrency_band_code = cb.concurrency_band_code
AND o.body_id = co.consortium_id
AND o.order_status = '4'
AND o.order_type IN ('P','G','S')
AND o.order_id = 10020743
since I created the trigger on ebook_order, then I need to remove that table in order to avoid mutating it is possible
to do something like script below
SELECT :new.order_id,
COALESCE (dl.isbn, cl.isbn, ol.product_id) eisbn,
CO.organisation_id,
:new.order_status,
:new.order_type,
CL.collection_id,
DECODE(cl.concurrency_flag, 0, 0, 1, cb.concurrency_limit) access_limit
FROM
ebook_isbn_data_load DL,
ebook_order_line OL,
ebook_collection_list CL,
ebook_concurrency_band CB,
consortium_organisation CO,
ebook_order O
WHERE :new.order_id = ol.order_id
AND ol.product_id = cl.collection_id(+)
AND cl.isbn = dl.ean13_of_set(+)
AND :new:concurrency_band_code = cb.concurrency_band_code
AND :new.body_id = co.consortium_id
how about on this part? I'm not sure with this one
AND o.order_status = '4'
AND o.order_type IN ('P','G','S')
AND o.order_id = 10020743
unless I can put IF THEN statement if something like below code
If :new.order_status = 4 and (:new.order_type ='P' or :new.:new.order_type ='G' or :new.order_type='S') then
thanks in advanceHow about:
and :new.order_status = 4
and :new.order_type in ('P','G','S')
and :new.order_id = 10020743Though it strikes me as unusual to have a trigger that only does something when a particular order id is inserted.
BTW Please read {message:id=9360002} and follow the advice there. In particular
the bit about formatting your code and putting it between tags.
Also, try to get out of the habit of upper casing your SQL - it's very COBOL (i.e. old-fashioned and not much use). -
Trigger in mutation - Update another rows in the same table with a trigger
Hi ,
I try to do a before update trigger on a table , but the trigger is in mutation. I understand why it do that but my question is :
How can I update other rows in the same table when a UPDATE is made on my table??????
Here is my trigger :
CREATE OR REPLACE TRIGGER GDE_COMPS_BRU_5 BEFORE
UPDATE OF DEPARTEMENT--, DISCIPLINE, DEG_DEMANDE, CE_ETAB
ON GDEM.COMPOSITION_SUBV
FOR EACH ROW
Organisme : FQRNT-FQRSC
Date de création : 14-07-2011
Date de modification :
Modifié par :
Auteur : Johanne Plamondon
Description : Ce déclencheur s'executera lors de la modification
du responsable dans la table COMPOSITION_SUBV
DECLARE
V_OSUSER V$SESSION.OSUSER%TYPE;
V_PROGRAM V$SESSION.PROGRAM%TYPE;
V_TERMINAL V$SESSION.TERMINAL%TYPE;
V_MACHINE V$SESSION.MACHINE%TYPE;
V_MODULE V$SESSION.MODULE%TYPE;
V_LOGON_TIME V$SESSION.LOGON_TIME%TYPE;
V_AUDIT_ID NUMBER;
vSEQ NUMBER;
i NUMBER;
vID DEMANDE.ID%TYPE;
BEGIN
begin
SELECT OSUSER, PROGRAM, TERMINAL,MACHINE,MODULE, LOGON_TIME
INTO V_OSUSER,V_PROGRAM,V_TERMINAL,V_MACHINE,
V_MODULE,V_LOGON_TIME
FROM V$SESSION
WHERE TYPE = 'USER'
AND USERNAME = USER
AND LAST_CALL_ET IN (0,1)
AND ROWNUM < 2;
exception when others then null; end;
IF NVL(:NEW.SC_PART,' ') = 'CHC' THEN
SELECT COUNT(*)
INTO i
FROM DEMANDE
WHERE DEM_REF = :NEW.DEM_ID
AND PER_NIP = :NEW.PER_NIP;
IF i = 1 THEN
SELECT ID
INTO vID
FROM DEMANDE
WHERE DEM_REF = :NEW.DEM_ID
AND PER_NIP = :NEW.PER_NIP;
UPDATE COMPOSITION_SUBV
SET --CE_ETAB = :NEW.CE_ETAB,
--DISCIPLINE = :NEW.DISCIPLINE,
DEPARTEMENT = :NEW.DEPARTEMENT,
--DEG_DEMANDE = :NEW.DEG_DEMANDE,
DATE_MODIF = SYSDATE,
USER_MODIF = V_OSUSER
WHERE DEM_ID = vID
AND PER_NIP = :NEW.PER_NIP
AND ANNEE = :NEW.ANNEE;
END IF;
END IF;
/*EXCEPTION
WHEN OTHERS THEN
NULL;*/
END;A standard disclaimer, the mutating trigger error is telling you that you really, really, really don't want to be doing this. It generally indicates a major data model problem when you find yourself in a situation where the data in one row of a table depends on the data in another row of that same table. In the vast majority of cases, you're far better off fixing the data model than in working around the problem.
If you are absolutely sure that you cannot fix the data model and must work around the problem, you'll need
- A package with a collection (or global temporary table) to store the keys that are modified
- A before statement trigger that initializes the collection
- A row-level trigger that adds the keys that were updated to the collection
- An after statement trigger that iterates over the data in the collection and updates whatever rows need to be updated.
If you're on 11g, this can be simplified somewhat by using a compound trigger with separate before statement, row-level, and after statement sections.
Obviously, though, this is a substantial increase in complexity over the single trigger you have here. That's one of the reasons that it's generally a bad idea to work around mutating table exceptions.
Justin -
Getting all_tab_columns.data_default in a ddl trigger
Under 10.1.0.3 I'm working on an AFTER CREATE or ALTER on DATABASE system trigger, and I'm querying all_tab_columns in the trigger body. It seems that if the trigger fires in response to DDL that modifies a column's default value, then all_tab_columns.data_default is giving me the column's old default. I want to get the current default value. If I create the table or add a column, then, in the resulting fire of the system trigger, all_tab_columns.data_default seems to be correct.
Is this documented behavior? Should I be looking somewhere (or somewhen) else for the column default?Thanks.
I tried working around this by putting my code into a procedure, and then using the DDL trigger to create a job that runs the code. My idea was to defer the all_tab_columns query until after the DDL trigger was done, and thus get a clean look at the data dictionary.
I put what looks like the appropriate dbms_scheduler calls into the trigger, but when I then execute DDL to fire the trigger I get "ORA-04092: cannot in a trigger"
The doc for this error number says that I am trying to commit or rollback in a trigger, but I'm not explicitly doing that. Also, the error message is supposed to have either the word "commit" or the word "rollback" in the message to tell me what I am doing. Instead, though, the error message just has a space there.
Maybe I'll start a TAR and see if 10.1.0.3 can get appended to the growing list of versions tied to this bug.
Maybe you are looking for
-
Can't connect to lcd projector in boot camp windows 7
I have a 13" macbook pro with Intel HD graphics 4000 running 10.7.4. When on the PC side the computer will not recognize the projector. I have downloaded the latest intel drivers and still nothing. I am using the same adapter that I used with an o
-
[svn:osmf:] 15759: Extending unit tests.
Revision: 15759 Revision: 15759 Author: [email protected] Date: 2010-04-27 07:46:27 -0700 (Tue, 27 Apr 2010) Log Message: Extending unit tests. Modified Paths: osmf/trunk/framework/OSMFTest/org/osmf/containers/TestHTMLMediaContainer.as
-
How to link dataTable component with Microsoft Access Database?
Please mail me @ [email protected]
-
PDF doc not re-opening properly in Illus CS2
I was working on a file in Illustrator CS2 and I saved it as a PDF with Illustrator editing capability. When I open the file again in Illus CS2, it is an OLD version of the file. However, the preview is the correct file and it is correct when I open
-
Changing standard.joboptions file?
Is there a way to change the settings in the standard.joboptions file? We are using Acrobat 9 Standard on Windows XP and Windows 7. We need to change the default compatibility from Acrobat 6 to Acrobat 5, but it won't let us save it in the standard.