I have a database that among the others contains these two tables:
NARUDZBENICA(**SIFANAR**,DATUM,NAZIV,*SIFRADOB,SIFRAKATALOGA,SIFRAZAP,SIFRANACISP*)
DOBAVLJAC(**SIFRADOB**,NAZIV,MAIL,TELEFON,FAKS)
I need a statement trigger to update column 'naziv' in all rows in table NARUDZBENICA where SIFRADOB starts with '0' when I change column 'naziv' on DOBAVLJAC where SIFRADOB is a primary key.
This is what I came up with:
CREATE OR REPLACE TRIGGER "STATEMENT_DOB"
AFTER UPDATE OF NAZIV ON DOBAVLJAC
BEGIN
EXECUTE IMMEDIATE 'ALTER TRIGGER UPDATE_NAR_FRB DISABLE';
UPDATE NARUDZBENICA
SET NAZIV = (SELECT :OLD.NAZIV FROM DOBAVLJAC)
WHERE ROWNUM > 1 AND SIFRADOB = '%0';
EXECUTE IMMEDIATE 'ALTER TRIGGER UPDATE_NAR_FRB ENABLE';
END;
I don't know what you are trying to do disabling and enabling one trigger in another. Otherwise I can see pretty much what you're trying to do, I just don't understand why.
In plain language: when the field NAZIV in table DOBAVLJAC is updated, the old value of the field is saved to the same field in table NARUDZBENICA where the field SIFRADOB begins with the character '0'.
create or replace trigger STATEMENT_DOB
after update of NAZIV on DOBAVLJAC
begin
update NARUDZBENICA
set NAZIV = :old.NAZIV
where SIFRADOB like '0%';
end;
It just occurred to me why you may be disabling the other trigger. It is an update trigger on the other table that watches for that same field to, in turn, propagate the change to DOBAVLJAC. This would create an endless loop of updates. (It would also means you probably should be using the :new.NAZIV value rather than :old.NAZIV.)
There are several tricks to solve that problem. The more involved one is to rename both tables and create views with the original table names. The Instead Of trigger on each view updates the NAZIV changes to both tables. No looping.
That is a rather involved solution. A simpler one (involving fewer object changes) is to create a flag column in both tables. The value of this column is always NULL. When the trigger executes (and it will have to be the before
trigger), it checks the NEW value of the flag column. If it is still null, that means this is the first Update so sends an update to the other table. That update sets the NAZIV value to the new value and the flag field to any non-null value. The non-null value tells the other trigger that this is a propagation update so ends the propagation. It changes the :new.flag value to null (you never actually change the contents of the flag field in the table) and just allows the update. This logic would be the same in the trigger on both tables.
This is made a little easier with Oracle 12c and invisible columns. It just allows you to hide the flag field from normal view so people aren't always coming around and asking what it is for.
In reading over my description, I don't think I made my point clearly, especially for non-native English speakers. So here is the trigger code:
create or replace trigger STATEMENT_DOB -- UPDATE_NAR_FRB
before update of NAZIV, Flag on DOBAVLJAC -- NARUDZBENICA
begin
if updating( Flag ) and not updating( NAZIV ) then
-- Someone playing around updating Flag only. Don't allow.
:new.FLAG := null;
elsif :new.FLAG is null then
-- Original Update. Propagate to other table
update NARUDZBENICA -- DOBAVLJAC
set NAZIV = :new.NAZIV,
Flag = 1
where SIFRADOB like '0%';
else
-- This was propagation from other table. Just allow the update of NAZIV
-- but first reset the flag...
:new.FLAG := null;
end if;
end;
That is not quite production-level coding, but I hope it illustrates the idea.
:new
or :old
identifiers can only be used in row-level
triggers. For statement level
trigger use of :new
and :old
identifiers is forbidden. Also you cannot commit
in a trigger. So incase you want to do any DML operation you need to use an autonomous
transaction. See below how you can do it.
This trigger will be fired for any change in column value of ID
in table A_TABLE
. The new value will be captured and passed on to the anonymous transaction.
CREATE OR REPLACE TRIGGER STATEMENT_DOB
AFTER UPDATE OF ID ON A_TABLE
for each row
BEGIN
proc_upd_tb(:new.id);
END;
Autonomous Transaction:
Data can be updated here and committed as shown.
create or replace procedure proc_upd_tb(id number)
as
PRAGMA AUTONOMOUS_TRANSACTION;
begin
UPDATE AA
SET A = id;
where <condition> ;
commit;
end;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.