That is what I did.
Koshal, November 27, 2006 - 11:51 am UTC
In the question I asked, I used the when clause. I am just asking is there anything other way than when clause. (Because when clauses does the required and takes time)
for example
update emp set sal=sal+10
in this update statement there is no user/status column. So I dont want to do any checking.
update emp set sal=sal+10,staus=nvl(status,'COMPLETE');
In this case I do want to do the checking.
With when clause even though the body does not get fired, it takes timing for checking here are stats I found.
No of Records Without Trigger With Trigger Trigger with When Clause
323336 Run 1 16 Seconds 51 Seconds 28 seconds
323336 Run 2 16 Seconds 52 Seconds 28 seconds
323336 Run 3 20 Seconds 248 Seconds
Thanks
Koshal
November 27, 2006 - 7:36 pm UTC
the when clause is the way to have the trigger check to see if it should fire the body or not.
checking is "going to consume some time", absolutely.
(you sort of DO want to do checking, else it would - well - always fire)
What happens when you do this ?
A reader, November 27, 2006 - 11:20 pm UTC
What happens when you do --
before update of user_id or update of stts_id or delete on
November 28, 2006 - 7:13 am UTC
that would help "filter" it as well.
Checking at the statement level
koshal, November 28, 2006 - 9:25 am UTC
What I mean is we should have some sort of checking at the statement level itself. What is happening in the when clause is it is checking for each row.
It should be able to distinguish between
1. upate emp set sal=sal+10
and
2. update emp set status=nvl(status,'COMPLETE')
Looking at the the first statement we know that there is going to be no change to "status". I would be nice had oracle able to identify this at statement level and eliminate row level checking.
Thanks a lot tom.
Thanks
Koshal
November 28, 2006 - 9:41 am UTC
did you see the comment right above this?
trigger on columns
Matteo, November 28, 2006 - 11:46 am UTC
Hi,
you can create a trigger for actions to specific columns:
SQL> set serveroutput on size 10000
SQL>
SQL> create table trigmat (nome varchar2(30), cognome varchar2(30))
2 /
Table created
SQL>
SQL> create or replace trigger trigmat_update_nome
2 before update or delete of cognome on trigmat
3 for each row
4
5 begin
6 dbms_output.put_line('cognome modified, old: '||:old.cognome||', new: '||:new.cognome);
7 end;
8 /
Trigger created
SQL>
SQL> insert into trigmat values ('john','smith');
1 row inserted
SQL> insert into trigmat values ('albert','red');
1 row inserted
SQL> commit;
Commit complete
SQL>
SQL> update trigmat set nome = upper(nome) where nome = 'john';
1 row updated
SQL> commit;
Commit complete
SQL>
Trigger didn't fire....
SQL> update trigmat set cognome = upper(cognome) where cognome = 'smith';
cognome modified, old: smith, new: SMITH
1 row updated
SQL> commit;
Commit complete
SQL>
Now, on update of cognome field, trigegr fired...
SQL> delete trigmat where cognome ='red';
cognome modified, old: red, new:
1 row deleted
SQL> commit;
Commit complete
SQL>
Also on delete.
Regards
Matteo
context switch
A reader, November 28, 2006 - 11:50 am UTC
Tom,
one question on this. With any PLSQL code (which trigger is) there is a context switch - correct? Is it also true for WHEN clause in trigger? Is "WHEN" condition checked by PLSQL engine (not sure I'm correct with terminology) or Oracle is smart enough to do it in SQL context and in case condition fails escapes context switch?
thank you very much!
November 28, 2006 - 12:45 pm UTC
benchmark it.
Thanks a lot Matteo
koshal, November 29, 2006 - 2:45 pm UTC
This is what I looking for !
Thanks
Koshal
Using Query in trigger WHEN condition
Megala, January 25, 2008 - 7:06 pm UTC
Tom,
Is it possible to use "Query" in WHEN condition of the TRIGGER clause with OR condition:
This trigger (AFTER INSERT OR UPDATE ROW) should fire only on the following condition :
when :NEW.<COLUMN> IS NOT NULL OR (SELECT ... FROM OTHER TABLE WHERE <CONDITION> IS TRUE) ;
DOES Trigger support this construct in where condition.
Oracle 10.2.0.1
Thanks
January 28, 2008 - 6:59 am UTC
It does not and be careful with that.
It looks like you have intertable dependencies. If something exists in another table (t2) and I create a row in this table (t1) then something has to be true.
That would imply that tables T1 and T2 must be mutually exclusive from an access perspective - any operation on T2 would involve locking T1 and vice versa.
Do you know why?
column trigger
sam, June 14, 2011 - 9:14 pm UTC
TOm:
just curious on why you advised to use "when" caluse to filter the trigger update when you can do
CREATE OR REPLACE TRIGGER test
BEFORE UPDATE OF USER_ID ON test
FOR EACH ROW
Is not this more effective that using WHEN clause. I did not realize you can select columns in the update statement.
Figure 17-3
http://download.oracle.com/docs/cd/B10500_01/server.920/a96524/c18trigs.htm
June 17, 2011 - 11:58 am UTC
you can use the update of, but you need the when clause as well in order to capture only the changes.
How to prevent update on a Column.
Rajeshwaran, Jeyabal, April 21, 2012 - 9:17 am UTC
Tom:
I got an requirement to not allow the users to update a column (say the column x) in table 'T' (even the owner should not).
create table t(x number,y date);
insert into t (x,y) values(1,sysdate);
commit;
If i need to make this table such that no modifications to be done. I can make it a read-only in 11g or enable a check constraint like below.
alter table t read only;
alter table t add constraint t_chk check(1=0) enable novalidate;
How can i defined a check such that any user (even the owner) can insert the records into column 'x' but no update should be done on column 'x'? Is that something can be achieved without using Triggers?
April 22, 2012 - 9:10 am UTC
you cannot really truly prevent the owner. Unless you lock the owners account.
Never grant anything on that column (do not grant update)
Do not put code into the schema owner
Lock the schema owner except for upgrades
sure, you could use a trigger and make everything slower for everyone (and still not solve the problem, I'm the owner, I'll just disable it).
I'd go with
do not grant
do not have code in owners schema (since that doesn't need grant, table schemas shouldn't have code anyway in most cases)
do not allow owner to be a schema you log in as - it isn't necessary.
DBA's with "update any table" will of course be able to bypass that, but then again, they'd be able to bypass the trigger too - so so what.
And audit, enable auditing so you can detect a modification
And have undo retention set high so you can see a modification or use total recall.
Trigger Execution to supress
Rajeshwaran, Jeyabal, November 02, 2012 - 1:55 am UTC
Tom,
We have an 3rd party application that has triggers (nearly six for insert or update action) for deriving some logic
( i know you hate triggers & saw that in your slides "Triggers Trickery" )
Now we are about to develope a new module for this application. Where we are going to update some tables (say T, where Trigger exists) based on PK
which we read from a file.
We dont want (logic inside) the Trigger to be executed for this new-module (as per business use-case), so i took the following steps.
1) Define a new application context APP_CTX
2) set dbms_session.SET_CONTEXT('APP_CTX','FLAG','Y') as very first statement in new Package about to develope.
3) Redefine the trigger as " WHEN (SYS_CONTEXT('MY_CTX','FLAG') IS NULL) "
In this way, I am not disturbing the exising application and silently supress the Trigger execution for this new development.
a) This new module will be executed during business offhours (say 8pm -4am) monthly once.
b) we will establish a connection, run this package once in a month and disconnect. we dont do any more stuff in that same session/connection.
Do you see/feel any flaw in this logic (or) any better way of doing this?
If you need i can show my script, which i used for testing.
November 05, 2012 - 8:32 am UTC
does the 3rd party application owner care you are doing this? Many 3rd party software owners would say "you are no longer supported if you do that"
Trigger Execution to supress
Rajeshwaran, Jeyabal, November 05, 2012 - 8:52 pm UTC
does the 3rd party application owner care you are doing this? Many 3rd party software owners would say "you are no longer supported if you do that"
We have informed them and they are fine with this. I would like to know your thoughts.
November 06, 2012 - 7:45 am UTC
it seems risky, I wouldn't let you do it. The trigger are there for a purpose - you are bypassing that purpose. It could have serious downstream impact.
This seems like an enhancement request the vendor should be making - as part of their supported software offering.
yet another reason I like XAPI's (transactional API's) to data, instead of triggers, they could just code the logic and allow you to use the same api to access the data.
Trigger Exection to supress
Rajeshwaran, Jeyabal, November 06, 2012 - 8:27 pm UTC
Tom,
This seems like an enhancement request the vendor should be making I agree, they need "UPDATE OF col1, col2" trigger but what they have is "UPDATE" trigger. We have requested them to make code change but they are not willing to make changes.
The code which we are about to develope is a new application, which will be integrated with them and we are about to do an update like this
update t set col3 = 'xxx' where pk = :b1
Which will be impacted by their triggers, so we decided to bypass them in such a way that they will not be impacted by us.
November 07, 2012 - 7:41 am UTC
I still stand by my statement:
this is a change the vendor should be making, period. it is their application, you are an end user.
instead of rewriting their logic, why don't you just recreate the trigger with the when condition??? why have it fire and have your logic short circuit it when you could just have it "not fire"???
Auditing a SELECT
Sri, November 14, 2012 - 2:27 pm UTC
Tom
I remember reading a document in this site about capturing audit information on users that perform a SELECT on restricted columns, but do not remember how I came across. Do you have an example?
If C was a restricted column containing sensitive data and some one ran the following query,
SELECT A,B,C
FROM TAB1;
then I need to capture the following information:
1. Who ran the query
2. The table (optional)
3. The Column (optional)
Is 2 and 3 available from somehere as opposed to hard coding it?
Is the query itself stored somewhere?
Thanks
November 14, 2012 - 8:31 pm UTC
dbms_fga, read about it.