creating trigger - oracle

I have a table named info_1,with 3 columns those are id,name,and operation.
Now when we insert or update a row, a trigger fires to fill the operation column with the kind of triggering event we are performing, i.e either insert or update.. I am unable to create such a trigger where user only gives information about id,name and operation column fills by itself through trigger. need help.

You can set the operation using a case statement like this:
create or replace trigger info_1_tr
before insert or update on info_1
for each row
begin
:new.operation := case when updating then 'UPDATE' else 'INSERT' end;
end;
/

Related

oracle : Trigger not inserting records into table

I have a trigger but it's not inserting the records into target table.
create or replace trigger ins_det_trig1
after insert on Table_a
declare
pragma autonomous_transaction;
---
begin
insert into inf_det
select
a.loc_id,
a.genre_id,
to_char(a.emp_date,'yyyy-mm-dd'),
a.san_seq
from Table_b a ,
Table_a b
where
b.emp_date=a.emp_date
and b.genre_id=a.genre_id
and b.san_seq=a.san_seq;
commit;
exception
when others
Rollback;
end;
pls help me on this
First of all the trigger is invalid, so it won't do anything. You are using a variable named v_err that you don't declare.
Then, you are swallowing all exceptions. If something goes wrong, you fill that variable with the error code and then silently end the trigger. Thus you'll never get informed when the trigger fails.
But the main problem is that you are not using the trigger as you should use triggers in Oracle. The trigger is an after row trigger (AFTER INSERT ... FOR EACH ROW) and hence fires once per row on inserts of table_a rows. The values that got inserted in a new row can be accessed with :new, e.g. :new.business_date.
You, however, ignore these values and select from the table instead. But at the moment of your select the table is mutating. Let's say we write an insert statement that inserts two rows. The trigger fires two times. It is left to chance which row gets inserted first. Oracle sees this and when you are inside the trigger and try to select, it tells us that the content of the table is not deterministic, as the other row may already be in the table or not. We get a mutating table exception.
Having said this: It seems you want an after statement trigger. A trigger that fires after the insert of the rows is complete. For this to happen remove the FOR EACH ROW clause and the related REFERENCING clause, too.
create or replace trigger ins_det_trig1
after insert on Table_a
declare
...
begin
...
end;

Before-insert trigger gets 'too many rows' error

I have a trigger:
create or replace trigger trig
before insert on sistem
for each row
declare
v_orta number;
begin
SELECT v_orta INTO :new.orta_qiymet
FROM sistem;
v_orta:=(:new.riyaziyyat+:new.fizika)/2;
insert into sistem(orta_qiymet)
values(v_orta);
end trig;
When I insert a row:
insert into sistem(riyaziyyat,fizika) values(4,4)
I get an error:
Why am I getting that error?
This is fundamentally not understanding how triggers work. You can't generally select from the table the trigger is against, and a before-insert trigger shouldn't not insert into the same table again - as that would just cause the trigger to fire again, infinitely (until Oracle notices and stops it). You aren't even currently using the v_orta value you're attempting to query.
I suspect you think the trigger is instead of your original insert perhaps, and really you want to set the orta_qiymet value in the newly-inserted row automatically based on the other two columns you have supplied. To do that you don't (and can't) select those values; instead you refer to the :NEW pseudorecord as you are already doing, and then set the third column value in that same pseudorow:
create or replace trigger trig
before insert on sistem
for each row
begin
:new.orta_qiymet := (:new.riyaziyyat + :new.fizika)/2;
end trig;
/
There is a lot of information in the documentation; this is similar to one of the examples.

Oracle Trigger inserting row into custom table

I have a Post-Insert Oracle trigger that is simply going to be used to insert a row into a table when the triggered table has a record added to it. My code is a simple insert:
BEGIN
INSERT INTO R5CHECKLISTMAP(CLM_CHKLINECODE, CLM_SYSTEMCODE)
VALUES(10, 'TEST');
END;
However, I get the error:
ORA 01006 - Bind Variable does not exist POST-INSERT 10 Before Binding
I know this has to be something simple, but I cannot figure out what the problem could be.

Oracle Trigger to Update Existing Row

I have a trigger that looks something like this:
create or replace
TRIGGER cluster_check
before insert on my_table
FOR EACH ROW
when (passive_server = new.server)
begin
ROLLBACK;
UPDATE my_table
set (server,passive_server) = (passive_server,server) where passive_server = new.server;
end;
I am getting the error Error: ORA-04076: invalid NEW or OLD specification on compilation.
Essentially what I am trying to do is check on insert to see if the incoming server matches the passive server in another record and if so cancel the insert and swap the existing records passive and active servers.
What am I doing wrong?
A trigger on a table can't change the operation like this.
You could define a view on top of my_table, do the INSERT against the view, and then have an instead of insert trigger that changed the INSERT operation into an UPDATE. But then all your DML would have to go against the view rather than the table. You could potentially rename the table and then create a view named my_table to make that transition easier.
Before you go down that path, however, are you certain that you need a trigger in the first place? Are you sure that your application couldn't do something like call a stored procedure that would determine what to do or that it couldn't do a MERGE instead of an INSERT?

Mutating error on after insert trigger

The below code is giving a mutating error.
Can any1 pls help in solving this.
CREATE OR REPLACE TRIGGER aso_quote_cuhk_trigger
BEFORE INSERT
ON aso.aso_quote_headers_all
FOR EACH ROW
BEGIN
UPDATE aso.aso_quote_headers_all
SET quote_expiration_date=sysdate+90
where quote_header_id=:new.quote_header_id;
END;
/
In oracle there are two levels of triggers: row level and table level.
Row level triggers are executed for each row. Table level triggers executed per statement, even if a statement changed more then one row.
In a row level trigger, you cannot select/update the table itself that has the trigger: you will get a mutating error.
In this case, there is no need for an UPDATE statement. Just try this:
CREATE OR REPLACE TRIGGER aso_quote_cuhk_trigger
BEFORE INSERT
ON aso.aso_quote_headers_all
FOR EACH ROW
BEGIN
:new.quote_expiration_date=sysdate+90;
END;
/
EDIT Rajesh mentioned it is possible, that before inserting a new row, OP wants to update all other records in the aso_quote_headers_all table.
Well, this is feasible, but it's a little tricky. To do this properly, you will need
A pl/sql package and a variable in the package header that is modified by the triggers. This variable could be a list holding the IDs of newly inserted records. Row level after insert trigger would add a new ID to the list. The content of this package variable will be different for each different session, so let's call this variable session_variable.
Row level after insert trigger, that would add new ID to the session_variable.
Table level after insert trigger that would get IDs from the session_variable, process the ID and then remove it from the session_variable. This trigger could execute necessary selects/updates on the aso_quote_headers_all. After a newly inserted ID is processed, this trigger should make sure it gets removed from the session_variable.
I realise you must have resolved your issue by now. However I am adding this answer below to help anyone else facing similar problem as you and I faced.
I recently encountered mutating table (ORA-04091: table XXXX is mutating, trigger/function may not see it) issue and after searching around realised the Compound Triggers feature available in 11g. If you're on 11g following compound trigger would have solved your issue.
CREATE OR REPLACE TRIGGER aso_quote_cuhk_trigger
FOR INSERT ON aso.aso_quote_headers_all
COMPOUND TRIGGER
row_id rowid;
AFTER EACH ROW IS
BEGIN
row_id := :new.rowid;
END AFTER EACH ROW;
AFTER STATEMENT IS
BEGIN
UPDATE aso.aso_quote_headers_all
SET quote_expiration_date = sysdate+90
WHERE rowid = row_id;
END AFTER STATEMENT;
END aso_quote_cuhk_trigger;
/
A word about how it works. This compound trigger fires 2 events :
First is AFTER EACH ROW where we capture the rowid of newly inserted row
Next is AFTER STATEMENT where we update the table using rowid (captured during first event) in the WHERE clause.
A useful link if you want to read more about Compound Triggers.

Resources