Skip to Main Content
  • Questions
  • (Single Trigger with IF condition) OR (Multiple Trigger)

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Saminathan.

Asked: October 26, 2003 - 8:20 pm UTC

Last updated: March 25, 2004 - 8:56 pm UTC

Version: 8.1.7.3

Viewed 1000+ times

You Asked

Dear Tom,

Requirement:-
-------------
1) UpdateDate column should up updated for each update(row level)
2) CreateDate column should be updated for each insert(row level)

Question:-
----------
Which one of the following method would be better?

1) One trigger with IF condition(insert or update)
2) TWO separate trigger for INSERT and UPDATE

--------------------------------------------------
1) create or replace trigger trig_01
...
before INSERT OR UPDATE
begin

if INSERTING then
:new.createdate := sysdate;
:new.update := sysdate;
end if;

if UPDATING then
:new.update := sysdate;
end if;

end;
-------------------------------------------------
2)
A)
create or replace trigger trig_01
...
before INSERT

begin
:new.createdate := sysdate;
:new.update := sysdate;
end;

B)
create or replace trigger trig_02
...
before UPDATE

begin
:new.update := sysdate;
end;

----------------------------------------------------------

Thanks
Sami

and Tom said...

how about one trigger and defaults?


create table t ( ....., createdate date default sysdate, updatedate date default sysdate )

create trigger t before update on t for each row
begin
:new.updatedate := sysdate;
end;
/


that'll have the least impact on inserts (no impact) and require but one trigger on the update.

Rating

  (7 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

but we need change in timezone and replication should be handled

Saminathan Seerangan, October 27, 2003 - 2:13 pm UTC

Dear Tom,

Thank you so much for your prompt response.

But we have to handle replication and timezone change(to GMT)

For example
A)
IF (DBMS_REPUTIL.FROM_REMOTE = FALSE)
....
...

also timezone should be stored in GMT format.
B)
:NEW.CREATEDATE := NEW_TIME(SYSDATE,GETZONE,'GMT');


So we cannot simply go with DEFAULT values.

In this scenario what would you prefer? I mean (1)Single Trigger with IF condition OR (2)Multiple Trigger

Thanks again
-Sami

Tom Kyte
October 27, 2003 - 6:33 pm UTC



single trigger works for me. since both must always set updatedate anyway.

Ignore Replication (A) issue from my previous review

A reader, October 27, 2003 - 3:08 pm UTC


Is it the same?

Frank, October 28, 2003 - 5:18 am UTC

Maybe I am overlooking something, but your solution is not exactly the same as the original poster's:
You provide a default (= overrulable) value for creationdate.

If I insert ...(creationdate,...) values (sysdate - 1, ...), your solution will provide different results then the original

So you end up needing an insert trigger I guess.


Tom Kyte
October 28, 2003 - 8:02 am UTC



you would not insert those values obviously.

trigger

mo, March 15, 2004 - 4:15 pm UTC

Tom:

I have created an "before update trigger" on table "books" that sends an email of all books that get updated when their status changes from "W" to "S".

However, the email is getting sent for each book. I am trying to change that to a statement level trigger but then I seem to lost the access to "WHEN" clause and old and new variables.

Which one should I do that allows me to send 1 email if I update 10 books from a table with 100 books.

Thanks,



Tom Kyte
March 15, 2004 - 5:13 pm UTC

well, how can you have access to the :old and :new without a row by row trigger??

You can use the method outlined:

</code> http://asktom.oracle.com/~tkyte/Mutate/index.html <code>

in order to capture the information you want in the row triggers and then send the email from the AFTER trigger. Please use dbms_job to send email!! don't send email in "real time" -- not only is it slow -- but it is not transactional. if the insert/update rolls back -- the email will be sent if you do it directly, if you use dbms_job to send the email, the queue to the job queue will be rolled back as well (eg: only send mail when the update succeeded)

trigger

mo, March 24, 2004 - 6:27 pm UTC

Tom:

Would there be a problem of doing this?

a. Add a column (job_id) to table A.
b. Update A.job_id (with l_job) in the original update statment that updates the table instead of doing it using a trigger. I can get job id by:

SELECT sys.jobseq.nextval into l_job from dual;

c. Create a statement level after-update trigger on Table A that would schedule the job.

1. However How can I get the job id here since I can't select the table.record I have the trigger defined on.

2. WHen I ran the above SELECT statment in a trigger I kept getting an error that "invalid column name".



Tom Kyte
March 24, 2004 - 6:44 pm UTC

you BETTER NOT get it with that. You better not touch anything owned by sys.

I'm not clear on what you are doing here, no.




trigger

mo, March 24, 2004 - 7:10 pm UTC

Tom:

You refered me to a link before but I do not think it applies here:

Here is the problem:

I have table Books(book_no,process_date,status,job_id);

When user select several books for processing they update the book_date(sysdate) and status. They do that 20 books at a time (using powerbuilder client/oracle database).

What I need to do is schedule an reminder email seven days later that will get sent to shipping if processed books do not get shipped after 7 days.

TO get process_date (sysdate usuallly) I have to use row level trigger. Problem here I need to schedule one email job and not 20 jobs that will be sent if status did not change. I am trying to update job_id for each record with the same job_id and then schedule one email job for that job id. When shipping department creates a shipment for these books I will remove the job and no email will be sent.

I appreciate your help.



Tom Kyte
March 25, 2004 - 8:44 am UTC

if they do 20 in a single statement, the link (on mutating tables) most certainly applies.


if they do 20 in 20 separate statements -- well, then you need to modify your code to "save them up" -- you have an application issue, nothing automagical we can do in the database there.

trigger

mo, March 25, 2004 - 9:31 am UTC

Tom:

It is 20 different update statements. The problem is that I need to update 20 records with job id and send the email once for the 20 books.

I was thinking of doing it this way:

Create a job that rescedules itself every 24 hours. The job will run a procedure that checks table BOOKS for anything flagged to be processed. If any records exist, send email else rescedule job 24 hours later. I need to include in the procedure code to check if that status of those 20 books changed, so I can delete the job in case it exists since books were shipped before 7 days.

How would you do it? What do you mean by "I havr to save them up". Do you mean insert those 20 in a spearate table?

Tom Kyte
March 25, 2004 - 8:56 pm UTC

what you just suggested sounds reasonable.

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library