Home » SQL & PL/SQL » SQL & PL/SQL » After Trigger is not working .
After Trigger is not working . [message #360316] |
Thu, 20 November 2008 06:57 |
ashishsaha04
Messages: 2 Registered: November 2008
|
Junior Member |
|
|
We are having a trigger like this
1) The Trigger is written on a table TABLEONE. The TABLEONE contains columns KEYID,COL1,COL2
2) In the Trigger ,we are calling a stored Procedure STROREPROC1(:new.KEYID)
3) I am using following query in the stored procedure STROREPROC1
Select COL1,COL2 from TABLEONE Where KEYID = parameterkeyid
Question
1) I executed Update TABLEONE Set COL1 = ‘FOUR’, COL2 = ‘FIVE’ Where KEYID = ‘KEYONE’
2) Whether in the STROREPROC1, Select COL1,COL2 from TABLEONE Where KEYID = parameterkeyid
will retrieve FOUR and FIVE
Right now it is retrieving the old values in COL1 and COL2
|
|
|
Re: After Trigger is not working . [message #360318 is a reply to message #360316] |
Thu, 20 November 2008 07:01 |
JRowbottom
Messages: 5933 Registered: June 2006 Location: Sunny North Yorkshire, ho...
|
Senior Member |
|
|
When you were writing this post, did it once cross your mind to actuall post the code of the trigger and the procedure?
Regardless of the answer to that question, kindly post them now, to give us a fighting chance of figuringthis out.
|
|
|
|
Re: After Trigger is not working . [message #360405 is a reply to message #360341] |
Thu, 20 November 2008 21:16 |
|
Kevin Meade
Messages: 2103 Registered: December 1999 Location: Connecticut USA
|
Senior Member |
|
|
Unless his trigger is autonomous, in which case the trigger should return the row before it was updated even though this is an after update trigger. Thus one reason why using autonomous_transaction inside a trigger can be a really bad idea.
SQL> drop table tableone
2 /
Table dropped.
SQL>
SQL> create table tableone
2 (
3 keyid varchar2(10)
4 ,col1 varchar2(10)
5 ,col2 varchar2(10)
6 )
7 /
Table created.
SQL>
SQL> insert into tableone values ('KEYONE','THREE','FOUR');
1 row created.
SQL> commit;
Commit complete.
SQL>
SQL> select * from tableone;
KEYID COL1 COL2
---------- ---------- ----------
KEYONE THREE FOUR
SQL>
SQL> create or replace trigger aur_tableone
2 after update on tableone
3 for each row
4 declare
5 r1 tableone%rowtype;
6 begin
7 select *
8 into r1
9 from tableone
10 where keyid = :new.keyid;
11 raise_application_error(-20999,'(keyid,col1,col2)=('||r1.keyid||','||r1.col1||','||r1.col2||')');
12 end;
13 /
Trigger created.
SQL>
SQL> Update tableone Set COL1 = 'FOUR', COL2 = 'FIVE' Where KEYID = 'KEYONE';
Update tableone Set COL1 = 'FOUR', COL2 = 'FIVE' Where KEYID = 'KEYONE'
*
ERROR at line 1:
ORA-04091: table KEVIN.TABLEONE is mutating, trigger/function may not see it
ORA-06512: at "KEVIN.AUR_TABLEONE", line 4
ORA-04088: error during execution of trigger 'KEVIN.AUR_TABLEONE'
SQL>
SQL> create or replace trigger aur_tableone
2 after update on tableone
3 for each row
4 declare
5 pragma autonomous_transaction;
6 r1 tableone%rowtype;
7 begin
8 select *
9 into r1
10 from tableone
11 where keyid = :new.keyid;
12 raise_application_error(-20999,'(keyid,col1,col2)=('||r1.keyid||','||r1.col1||','||r1.col2||')');
13 end;
14 /
Trigger created.
SQL>
SQL> Update tableone Set COL1 = 'FOUR', COL2 = 'FIVE' Where KEYID = 'KEYONE';
Update tableone Set COL1 = 'FOUR', COL2 = 'FIVE' Where KEYID = 'KEYONE'
*
ERROR at line 1:
ORA-20999: (keyid,col1,col2)=(KEYONE,THREE,FOUR)
ORA-06512: at "KEVIN.AUR_TABLEONE", line 9
ORA-04088: error during execution of trigger 'KEVIN.AUR_TABLEONE'
SQL>
So, for those who don't get it, I ask you, why is your after update trigger seeing the row as it was before it was updated? The select statement should have picked up the updates right? But it didn't. You need to understand autonomous transactions to know why. Once you do you will realize why autonomous transactions inside a trigger are bad if you are using them to effect a specific kind of business logic instead of using them to simply audit with.
The OP is likely not creating and after update trigger as autonomous but this is related enough and fun enough to comment on.
Kevin
[Updated on: Thu, 20 November 2008 21:17] Report message to a moderator
|
|
|
|
|
Re: After Trigger is not working . [message #360598 is a reply to message #360516] |
Fri, 21 November 2008 09:56 |
|
Kevin Meade
Messages: 2103 Registered: December 1999 Location: Connecticut USA
|
Senior Member |
|
|
Are you telling us that you are indeed using AUTONOMOUS TRANSACTION as the mechanism to get your trigger to finish. If so we are telling you that this is bad coding because it has the logical error you are experieincing.
To solve such a problem you must remove the autonomous transaction from your trigger code. This will of course mean you can't write the trigger you want to write and must have a different approach to your problem. There are two solutions most people use:
1) do the work inside your applications instead. This gets around the problem but does not centralize the logic in any way so you must make certain that all access to the data contains the logic. It is the traditional way of doing it. It of course leads to the maintenance issues we are all familiar with. Unless you have a highly controled system development process, sooner or later someone will use a tool or write some code that does not have the logic you need and your data will get corrupted.
2) use INSTEAD-OF-TRIGGERS. This allows you to centralize logic and thus make sure that all applications will be using it. This would be my choice. It follows the same design philosophy as the trigger solution you were trying initialy. Nothing is perfect however. One downside to INSTEAD-OF-TRIGGERS is that they are an advanced feature. You will find that although all advanced features of oracle work, they don't necessarily work together in combination with other advanced features. For example, since instead of triggers involve use of a view layer, if the view is complex enough, there will be no root ROWID associated with it. Thus you cannot reference ROWID in your code on this view. If you have existing code that uses ROWID on specific tables, when you introduce INSTEAD-OF-TRIGGERS, this code may stop working an must be re-written. In the end this is not a bad thing as you should never have been using ROWID in a production solution anyway. Another example is MERGE. The MERGE statment will not run against views with INSTEAD-OF-TRIGGERS so if your code uses merge statements, you will have to re-write them too. This too in my mind may not be a bad thing for although MERGE can be faster that the traditional UPSERT logic in some cases, it is not actually a well understood database feature. It does not for example do what people think it does. Most people believe MERGE is the implementation of UPSERT (eg. update else insert logic), all in one statement. But it ain't. If you think it is, then you do not know how it works. For example, try creating a suite of triggers on a table along with some test data, then do a merge and see what triggers get fired. You will be confused. Imagine what this would do to auditing triggers?
But, will you please confirm your problem. You never actually posted any working code, nor said that you were using AUTONOMOUS TRANSACTIONS in your triggers. Are you?
As you can see, Michel and I sometimes have a difference of opinion on how to deal with newbies and the technology. I am happy to give newbies plenty of rope to hang themselves. I want to expose newbies to different thought processes and take advantage of their excitement and energy as a newbie, to get them looking at the power of Oracle as a development platform. I prefer guidence over protection as a way of working with newibies. But please let me be clear. Michel is correct in saying that I am not telling you to use AUTONOMOUS TRANSACTIONS inside your triggers. I am telling you not to do that. Additionally you should step back and understand the process you are working with before you jump into coding a solution for it. Lastly growth often requires pain. If you are going to use something new, find a mentor to assist you, or expect some pain.
Good luck, Kevin
|
|
|
|
|
|
|
Goto Forum:
Current Time: Thu Dec 05 16:28:08 CST 2024
|