[ Serbiankum @ 13.05.2009. 13:58 ] @
Ljudi nikako da u oracleu (express edition) napisem jedan triger.

Imam dve tabele koje su medjusobno povezane: Otpremnica za gorivo i stavka otpremnice za gorivo

Otpremniza za gorivo

BrojOtpr
Datum
SifraDistributera
UkupnaCena

StavkaOtpremnice za gorivo

RedniBroj
BrojOtpr
SifraGoriva
Naruceno
Istoceno
Cena


E sad, treba da napisem triger koji ce sve Cene u tabeli stavke otpremnice za gorivo sabirati i upisivati u tabelu otpremnica u polje ukupna cena. Da li je ovo izvodljivo?

NIkako da napisem valjan triger. Ako se pitate zasto je polje ukupnaCena u tabeli otpremnica to je zato sto zadatak treba da bude takav.

Svaki savet dobrodosao.

hvala

[Ovu poruku je menjao Serbiankum dana 13.05.2009. u 22:03 GMT+1]
[ Serbiankum @ 13.05.2009. 16:00 ] @
Ljudi svaka pomoc je znacajna. Uopste nemam predstavu kako ovo da izvedem.
[ brzak @ 13.05.2009. 16:17 ] @
sve hocu da ti odgovorim, a ne stizem od guzve

evo ti nesto na brzinu, nadam se da ce pomoci

stavi na blok sa stavkama jedno summrary field (sum_cena) koje ce ti sabirati polje cena

posle mozes na when-validate-record detail bloka staviti nesto tipa :otpremnica.ukupnacena := :stavka.sum_cena
[ Serbiankum @ 13.05.2009. 18:09 ] @
hvala na odgovoru, ali na zalost nisam bas najbolje razumeo. Moze li malo detaljnije?

Meni ta sumarna cena treba da se izracuna u polju UkupnaCena koja se nalazi u tabeli otpremnica a ne u tabeli stavkeOtpremnice. Kako bi to mogao najlakse da izvedem?

hvala
[ djoka_l @ 13.05.2009. 18:39 ] @
Pomogao bih ti da ne piše u tvom profilu "Diplomirani ekonomista iz kompjuterskog inzenjeringa, master studije na fonu".

Ako pokažeš da si nešto pokušao da uradiš, pomoći ću...

Pogledaj http://download.oracle.com/doc...8/xedev_triggers.htm#sthref802
i na ovom forumu: http://www.elitesecurity.org/t363791-pomoc-oko-trigera-sql-plus
[ Serbiankum @ 13.05.2009. 19:55 ] @
Nesto ovako sam pokusao ali ne radi:

Create or replace trigger ukupnacena
After insert of cena on STAVKEOTPRZAGORIVO
For each row
begin

select SUM (CENA)
from STAVKEOTPRZAGORIVO

insert into OTPRZAGORIVO (UKUPNACENA)

end;


E sad gde gresim?
Prvi put se susrecem sa trigerima i stvarno bi bila znacajna pomoc.

hvala
[ djoka_l @ 13.05.2009. 20:38 ] @
Ima tu više grešaka.

U PL/SQL kodu nije dozvoljeno

Code:
select SUM (CENA)
from STAVKEOTPRZAGORIVO


umesto toga mora konstrukcija:

Code:
select  lista_izraza
INTO lista_varijabli
from ...


Drugo, zašto select, pa insert. Ako je tabela STAVKEOTPRZAGORIVO povezana sa tabelom OTPRZAGORIVO preko spoljnog ključa koji sadrži BrojOtpr, tada slog u OTPRZAGORIVO sa datim BrojOtpr MORA da postoji.

Treće, treba da uradiš update samo sloga koji ima BrojOtpr jednak polju BrojOtprzagorivo.

Četvrto, vrednost polja BrojOtprzagorivo u insertovanom slogu se označava kao :new.BrojOtprzagorivo

Dakle, modifikuj program da radi update, a u where klauzuli koristi BrojOtpr = :new.BrojOtprzagorivo

I, poslednje, pročitaj deo Oracle manuala gde su objašnjeni trigeri u XE bazi.
[ Comii @ 13.05.2009. 21:01 ] @
Ako bi postavio kod za tabele pre bi smo dosli do resenja.
Mislim da ti samo ovaj insert- triger nece biti dovoljan, jer zamisli da ti neko izbrise neki unos cene ili uradi update. Moras imati triger i za slucaj insert i update a i delete.

Evo koda koji sam ja sastavio, ali ti kazem da bi mi lakse bilo kada bih imao te tabele.

CREATE OR REPLACE TRIGGER otpremnice_gor
AFTER INSERT OR UPDATE OR DELETE OF CENA ON svake_Otpremnice
FOR EACH ROW
BEGIN
IF DELETING THEN
UPDATE Otpremnica c set
c.UKUPNACENA=c.UKUPNACENA-:old.CENA;
END IF;
IF INSERTING THEN
UPDATE Otpremnica c set
c.UKUPNACENA=c.UKUPNACENA+:new.Cena;
END IF;
IF UPDATING THEN
UPDATE Otpremnica c set
c.UKUPNACENA =c.UKUPNACENA-:old.Cena+:new.Cena;
END IF;
END;


Proveri da li su imena tabela i polja koja su navedena u trigeru dobra.

[Ovu poruku je menjao Comii dana 13.05.2009. u 22:17 GMT+1]
[ djoka_l @ 13.05.2009. 21:21 ] @
@Comii Pa ti si mu sve rešio. Samo što ovaj kod nikada ne bi dao tačan rezultat jer je UkupnaCena na početku (verovatno) null, pa bi i sve ostale računske radnje s njom davale null. Fali nvl svuda gde koristiš ukupnu cenu...
[ Serbiankum @ 13.05.2009. 21:21 ] @
hvala za kod. Samo da napomenem da koristim Oracle express edition verziju.

Kod sam kompajlirao i nije pronasao nijednu gresku, ali kod nazalost ne radi. Tacnije ne sabira cene u tabeli stavkeotprzagorivo i ne upisuje vrednost u tabelu otpremnicazagorivo u polje ukupnaCena.

Okacio sam bazu na sledeci link (zauzima 15 kb)
http://rapidshare.com/files/232616241/baza.txt.html

Citam tutorijale na internetu ali nikako sam da resim ovaj triger. Hvala svima na dosadasnjoj pomoci

P.S evo uspeo sam da okacim bazu ovde na forumu umesto rapida
[ Comii @ 13.05.2009. 21:51 ] @
Da u pravu si djoka_l, nvl sam zaboravio.

Znaci bilo bi ovako:


CREATE OR REPLACE TRIGGER otpremnice_gor
AFTER INSERT OR UPDATE OR DELETE OF CENA ON svake_Otpremnice
FOR EACH ROW
BEGIN
IF DELETING THEN
UPDATE Otpremnica c set
c.UKUPNACENA=nvl(c.UKUPNACENA,0)-:old.CENA;
END IF;
IF INSERTING THEN
UPDATE Otpremnica c set
c.UKUPNACENA=nvl(c.UKUPNACENA,0)+:new.Cena;
END IF;
IF UPDATING THEN
UPDATE Otpremnica c set
c.UKUPNACENA =nvl(c.UKUPNACENA,0)-:old.Cena+:new.Cena;
END IF;
END;


[ djoka_l @ 13.05.2009. 21:56 ] @
Code:

CREATE OR REPLACE TRIGGER otpremnice_gor
AFTER INSERT OR UPDATE OR DELETE OF CENA ON svake_Otpremnice
FOR EACH ROW
BEGIN
  IF DELETING THEN
    UPDATE Otpremnica c set
    c.UKUPNACENA=nvl(c.UKUPNACENA,0)-:old.CENA
    where c.BrojOtpremnice = :old.BrojOtpremnice;
  END IF;
  IF INSERTING THEN
    UPDATE Otpremnica c set
    c.UKUPNACENA=nvl(c.UKUPNACENA,0)+:new.Cena
    where c.BrojOtpremnice = :new.BrojOtpermnice;
  END IF;
  IF UPDATING THEN
    UPDATE Otpremnica c set
    c.UKUPNACENA =nvl(c.UKUPNACENA,0)-:old.Cena+:new.Cena
    where c.BrojOtpremnice = :old.BrojOtpremnice;
  END IF;
END;


Naravno, zaboravio sam da spomenem da fali i where uslov.
[ Serbiankum @ 13.05.2009. 22:42 ] @
Ljudi hvala vam na pomoci triger radi. Evo ceo triger sa pravim imenima:

CREATE OR REPLACE TRIGGER "OTPREMNICE_GOR"
AFTER INSERT OR UPDATE OR DELETE OF CENA ON STAVKEOTPRZAGORIVO
FOR EACH ROW
BEGIN
IF DELETING THEN
UPDATE OTPRZAGORIVO c set
c.UKUPNACENA=nvl(c.UKUPNACENA,0)-:old.CENA
where c.BROJOTPRZAGORIVO = :old.BROJOTPRZAGORIVO;
END IF;
IF INSERTING THEN
UPDATE OTPRZAGORIVO c set
c.UKUPNACENA=nvl(c.UKUPNACENA,0)+:new.Cena
where c.BROJOTPRZAGORIVO = :new.BROJOTPRZAGORIVO;
END IF;
IF UPDATING THEN
UPDATE OTPRZAGORIVO c set
c.UKUPNACENA =nvl(c.UKUPNACENA,0)-:old.Cena+:new.Cena
where c.BROJOTPRZAGORIVO = :old.BROJOTPRZAGORIVO;
END IF;
END;


Posto mi je cilj da zaista razumem triger, pitao bih vas sledece:

1. Sta tacno znaci UPDATE OTPRZAGORIVO c set. Takodje sta znaci ovo "c" ? Da li je to varijabla

2. Sta znaci c.UKUPNACENA,0. Koju funkciju ima nula

3. Sta tacno znaci +:new.Cena Znam da new predstavlja novu vrednost, da li bi to trebalo da predstavlja novu vrednost cene?

4. where c.BROJOTPRZAGORIVO = :new.BROJOTPRZAGORIVO; Da li uz pomoc ovoga mi spajamo tabele Otpremnica i stavka otpremnice.

hvala
[ djoka_l @ 13.05.2009. 22:43 ] @
Evo ti kompletnog koda sa uprošćenom šemom baze. Možeš da dodaš još primera da bi video kako ovo zaista i radi.

Kada god tražiš pomoć, uvek je korisno da priložiš sličan skript kao ovaj koji sam ja stavio, kako bi i drugi mogli da brzo naprave testne tabele i isprave greške u kodu.

Code:

CREATE table "OTPREMNICEGORIVA" (
    "BROJOTPREMNICE" NUMBER NOT NULL,
    "CENA"           NUMBER,
    constraint  "OTPREMNICEGORIVA_PK" primary key ("BROJOTPREMNICE")
)
/

CREATE table "STAVKEOTPREMNICEGORIVA" (
    "BROJOTPREMNICE"  NUMBER NOT NULL,
    "REDNIBROJSTAVKE" NUMBER NOT NULL,
    "CENA"            NUMBER
)
/

alter table "STAVKEOTPREMNICEGORIVA" add constraint 
"STAVKEOTPREMNICEGORIVA_PK" primary key ("BROJOTPREMNICE","REDNIBROJSTAVKE")
/

ALTER TABLE "STAVKEOTPREMNICEGORIVA" ADD CONSTRAINT "STAVKEOTPREMNICEGORIVA_FK" 
FOREIGN KEY ("BROJOTPREMNICE")
REFERENCES "OTPREMNICEGORIVA" ("BROJOTPREMNICE")

/
create or replace trigger "STAVKEOTPREMNICEGORIVA_T1"
AFTER
insert or update or delete on "STAVKEOTPREMNICEGORIVA"
for each row
begin
  IF DELETING THEN
    UPDATE OtpremniceGoriva c set
    c.CENA=nvl(c.CENA,0)-nvl(:old.CENA,0)
    where c.BrojOtpremnice = :old.BrojOtpremnice;
  END IF;
  IF INSERTING THEN
    UPDATE OtpremniceGoriva c set
    c.CENA=nvl(c.CENA,0)+nvl(:new.Cena,0)
    where c.BrojOtpremnice = :new.BrojOtpremnice;
  END IF;
  IF UPDATING THEN
    UPDATE OtpremniceGoriva c set
    c.CENA =nvl(c.CENA,0)-nvl(:old.Cena,0)+nvl(:new.Cena,0)
    where c.BrojOtpremnice = :old.BrojOtpremnice;
  END IF;

end;
/   
insert into otpremnicegoriva (BrojOtpremnice,cena) values (1, null);
insert into otpremnicegoriva (BrojOtpremnice,cena) values (2,0);

select * from otpremnicegoriva;

insert into stavkeotpremnicegoriva (brojotpremnice,rednibrojstavke,cena) values (1,1,22);

select * from otpremnicegoriva;
[ djoka_l @ 13.05.2009. 22:49 ] @
U isto vreme postujemo...

Citat:
1. Sta tacno znaci UPDATE OTPRZAGORIVO c set. Takodje sta znaci ovo "c" ? Da li je to varijabla

2. Sta znaci c.UKUPNACENA,0. Koju funkciju ima nula

3. Sta tacno znaci +:new.Cena Znam da new predstavlja novu vrednost, da li bi to trebalo da predstavlja novu vrednost cene?

4. where c.BROJOTPRZAGORIVO = :new.BROJOTPRZAGORIVO; Da li uz pomoc ovoga mi spajamo tabele Otpremnica i stavka otpremnice.


1. c je alias za naziv tabele. Set je deo sintakse UPDATE komande. Da bi specificirao u nekom upitu koji u sebi ima više tabela kolonu, moraš da koristiš oblik ime_tabele.ime_kolone ili alias.ime_kolone ili samo ime_kolone, ali samo u slučaju da više tabela iz upita nemaju kolonu sa istim imenom.

2. nije c.UKUPNACENA,0 nego NVL(c.UKUPNACENA,0). NVL je funkcija koja vraća vrednost prvog argumenta ukoliko je on različit od null ili drugog, ako je prvi null.

3. :new.ime_kolone je vredost kolone koja je "nova". Definisana je u slučaju ON INSERT i ON UPDATE trigera. :old.ime_kolone je "stara" vrednost kolone i definisana je u ON DELETE i ON UPDATE trigeru.

4. da
[ Serbiankum @ 13.05.2009. 23:15 ] @
1. znaci c.UKUPNACENA je isto sto i otprzagorivo.ukupnacena

2. nvl je ustvari univerzalna funkcija.radi i ako je razlici od nule ili ako je null, Sta znaci ova nula u zagradi NVL(c.UKUPNACENA,0).

3. Zanima me tacno kako ovo funkcionise: c.UKUPNACENA=nvl(c.UKUPNACENA,0)+:new.Cena Kako izracunava? Da li smo ovde mogli da stavimo SUM nesto kao SUM(cena) ?

4. where c.BROJOTPRZAGORIVO = :old.BROJOTPRZAGORIVO; Posto ovde c znaci otprzagorivo = old. Da li ovo old predstavlja stavkuotprzagorivo tabelu ili neku staru vrednost?

hvala

[ djoka_l @ 13.05.2009. 23:30 ] @
1. da - alias je neobavezni deo sintakse koji se koristi za skraćeno pisanje
2. nvl je funkicja sa dva argumenta: nvl(arg1, arg2) = arg1 ako je arg1 različit od null, inače arg2. To je kao da napišeš
IF arg1 not null then return arg1 else return arg2 end if; nvl(arg1,0) znači da će funkcija vratiti vrednost 0 (nula) ako je arg1 null. null je ništa - nije broj. 1 + 0 = 1, 1 + null = null
3. nema smisla stavljati sum, zato što se triger "ispaljuje" POSLE SVAKOG INSERTOVANOG SLOGA (after insert ... for each row). Zašto bi, na primer, posle inserta hiljadu prvog sloga stavke ponovo dohvatao svih 1001 stavki da računaš sum.
4. TRIGER se definiše nad TABELOM. :old. i :new. se odnose na vrednosti u slogu tabele nad kojim je definisan triger. Shvati to kao da triger ima dva implicitna objekta (kod UPDATE) ili jedan (kod INSERT i DELETE) koji predstavljaju slogove tabele koji su prouzrokovali da triger "opali"
[ Serbiankum @ 16.05.2009. 09:35 ] @
Pokusavam da napravim sledeci triger:

Imamo tabelu distributer (SifraDistributera i NazivDistributera) i tabelu Otpremicazagorivo (BrojOtpr,datum,SifraDistributera,NazivDistributera). Triger treba da omoguci da ako u tabeli otpremnicazagorivo upisemo SifruDistributera da se u polju NazivDistributera ispise njegov naziv.

U prethodnih par postova imate bazu koju sam okacio.

Ideja je sledeca:

Code:

CREATE OR REPLACE TRIGGER "Triger" 
AFTER INSERT or update OF sifradistributera ON otprzagorivo
FOR EACH ROW
BEGIN
  
  IF INSERTING THEN
    UPDATE OTPRZAGORIVO c set
    c.nazivdistributera = :old.nazivdistributera
    where c.sifradistributera = :new.sifradistributera;
  END IF;
END;


Triger kad se kompajlira ne prikazuje gresku ali prilikom testiranja javlja gresku "mutating"
[ djoka_l @ 16.05.2009. 11:08 ] @
Spomenuo si tsbelu (šifarnik) distributera a nje nema u kodu...
Kako bi našao naziv distributera, ako imaš njegovu šifru?

Code:

begin
   select nazivdistributera
   into :new.nazivdistributera
   from distributer d
   where d.sifradistributera = :new.sifradistributera;
endč


A i loš ti je običaja da trigeru daš naziv "Triger" , bolje bi bilo da se zove, na primer, otprzagorivo_t1.
[ Comii @ 16.05.2009. 11:08 ] @
Pokušaj nešto ovako da ubacis u telo trigera:


UPDATE OTPRZAGORIVO c set
c.nazivdistributera=DISTRIBUTER.nazivdistributera
where DISTRIBUTER.sifradistributera = :new.sifradistributera;
[ djoka_l @ 16.05.2009. 11:19 ] @
Comii, bolje obriši taj kod, neće raditi...
[ Serbiankum @ 16.05.2009. 14:13 ] @
Sa ovim kodom postoji greska DISTRIBUTER"."SIFRADISTRIBUTERA": invalid identifier
Code:

CREATE OR REPLACE TRIGGER "triger1" 
AFTER INSERT or update OF sifradistributera ON otprzagorivo
FOR EACH ROW
BEGIN

IF INSERTING THEN

UPDATE OTPRZAGORIVO c set
c.nazivdistributera=DISTRIBUTER.nazivdistributera
where DISTRIBUTER.sifradistributera = :new.sifradistributera;
 END IF;
END;



Sa drugim kodom postoji greska Encountered the symbol "end-of-file" when expecting one of the following: begin case declare end exception exit for goto if loop mod null pragma raise return select update while with


Code:

CREATE OR REPLACE TRIGGER "triger2" 
AFTER INSERT or update OF sifradistributera ON otprzagorivo
FOR EACH ROW
BEGIN
  
begin
   select nazivdistributera
   into :new.nazivdistributera
   from distributer d
   where d.sifradistributera = :new.sifradistributera;
end;


[Ovu poruku je menjao Serbiankum dana 16.05.2009. u 15:40 GMT+1]
[ djoka_l @ 16.05.2009. 21:36 ] @
Izvini, a šta će ti dva BEGIN. Ja sam tebi dao kompletan kod koji treba da zameni ceo tvoj begin .. end block, a ti si ostavio višak begina.
[ Serbiankum @ 16.05.2009. 23:28 ] @
Triger radi jedino ako napisem before, ako je after onda ne radi i javlja gresku ORA-04084: cannot change NEW values for this trigger type.

Jer zamisao je bila da cim se unese sifra distributera da se odmah upise naziv distributera u polje "naziv distriutera". To sada togadja ali tek kada napravim novu stavku odnosno kada je stavka commit.

Da li nekako triger moze da bude AFTER INSERT or update umesto BEFORE?
[ jaksic24 @ 17.05.2009. 04:21 ] @
Probaj ovako:

create or replace TRIGGER OTPRZAGORIVO_AFT_U_ROW
After update of nazivdistributera on DISTRIBUTER
For each row
begin
UPDATE OTPRZAGORIVO c set
c.nazivdistributera = :new.nazivdistributera
where c.sifradistributera = :old.sifradistributera;
end;


[ Serbiankum @ 17.05.2009. 10:10 ] @
zasto triger jedino radi sa before insert or update a ne radi kad se napise after insert or update. Jer cilj je bio da tek kada se upise sifradistributera odmah pojavi i naziv distributera, a ne da se naziv pojavi kada predjem u novi red ili novu stavku. Mislim odgovara i ovako ali me zanima da li taj naziv moze da se pojavi odmah posle upisivanja sifre distributera.

Pitanje vazano za ovaj deo koda:

begin
select nazivdistributera
into :new.nazivdistributera
from distributer d
where d.sifradistributera = :new.sifradistributera;
end;


1. select nazivdistributera, da li se misli na nazivdistributera u tabeli otprzagorivo?
2. into :new.nazivdistributera, sta ovo tacno znaci? Da li ovo znaci da ubacuje novu vrednost distributera u tabelu otprzagorivo?



[Ovu poruku je menjao Serbiankum dana 17.05.2009. u 11:20 GMT+1]

[Ovu poruku je menjao Serbiankum dana 17.05.2009. u 11:22 GMT+1]
[ djoka_l @ 17.05.2009. 10:36 ] @
Prvo, tačno je da triger treba da bude before, nisam obratio pažnju na deklaraciju treigera.

Drugo, triger radi tačno ono što treba da radi, ali to nije ono što si ti zamislio da on radi. Pretpostavljam da ti želiš da se naziv distributera pojavi na ekranu u aplikaciji. To onda ne može trigerom u bazi, mora se napisati u aplikaciji, s tim da ja pojma nemam šta koristiš da napraviš aplikaciju, APEX, FORMS ili nešto drugo.

I, zaboga, batali Oracle ako ne znaš da napišeš najobičniji SELECT. Kakvo je to pitanje? Zar ne znaš za šta ti služi FROM deo SELECT naredbe.
Da li razumeš za šta služi kod:

select nazivdistributera
from distributer d
[ Serbiankum @ 17.05.2009. 10:52 ] @
Zasto triger treba da bude before?Ja sam mislio da moze after da cim se upise sifradistributera (a to je posle odnosno after) da se u polje nazivdistributera odmah upise naziv. Ako to ne moze u bazi onda ok.Ponavljam triger otprilike radi to sto sam i hteo jer na kraju ipak ispisuje naziv distributera kada se unese sifra distributera. Znam da to moze u aplikaciji ali sam mislio da mozda moze i u bazi. Inace koristim toad za testiranje.

Drugo, znam da koristim select i from naredbe, nego me je zbunio redosled. Jer prvo je isao select pa into pa from.
[ djoka_l @ 17.05.2009. 11:17 ] @
Assigning Values to a Variable With the PL/SQL SELECT INTO Statement

Another way to assign values to a variable is by selecting (or fetching) database values into it. With the PL/SQL SELECT INTO statement, you can retrieve data from one row in a table. In Example 4-13, 10 percent of the salary of an employee is selected into the bonus variable. Now, you can use the bonus variable in another computation, or insert its value into a database table.

In the example, the DBMS_OUTPUT.PUT_LINE procedure is used to display output from the PL/SQL program. For more information, see "Inputting and Outputting Data with PL/SQL".

Example 4-13 Assigning Values to Variables Using PL/SQL SELECT INTO

DECLARE -- declare and assign values
bonus_rate CONSTANT NUMBER(2,3) := 0.05;
bonus NUMBER(8,2);
emp_id NUMBER(6) := 120; -- assign a test value for employee ID
BEGIN
-- retreive a salary from the employees table, then calculate the bonus and
-- assign the value to the bonus variable
SELECT salary * bonus_rate INTO bonus FROM employees
WHERE employee_id = emp_id;
-- display the employee_id, bonus amount, and bonus rate
DBMS_OUTPUT.PUT_LINE ( 'Employee: ' || TO_CHAR(emp_id)
|| ' Bonus: ' || TO_CHAR(bonus) || ' Bonus Rate: ' || TO_CHAR(bonus_rate));
END;
/

Pročitaj dokument koji sam ti stavio u linku: http://www.oracle.com/pls/xe102/homepage
najbolje da kreneš od "2 Day Developer Guide"
[ Serbiankum @ 20.05.2009. 17:35 ] @
jos jedno pitanje za trigere. U tabeli stavke otpremnice za gorivo postoje polja naruceno i istoceno goriva. Zamisao je da ako je naruceno 5t goriva a ako se u polje istoceno upise vrednost koja je veca od istoceno (u ovom slucaju 5) da se pokrene triger koji ce ispisati u polje istoceno vrednost naruceno.

Probao sam da resim ovaj problem sa if then ali opet se pojavljuje problem mutating.

Code:

CREATE OR REPLACE TRIGGER "istoceno" 
before insert or update of istoceno on stavkeotprzagorivo
For each row

begin 

if :new.istoceno > :old.naruceno then
insert into stavkeotprzagorivo (istoceno) values (:old.naruceno);
  
end if;
end;



Da li moze da se resi problem sa if then ?
[ djoka_l @ 20.05.2009. 18:27 ] @
Još uvek ne razumeš trigere...

:old NE MOŽEŠ da koristiš u ON INSERT trigeru - nije definisano, ne postoji

Kako možeš u triger ON INSERT OR UPDATE nad tabelom stavkeotprzagorivo da radiš insert/update u tu istu tabelu!!! Poznat ti je pojam beskonačne petlje?

Šta ovo znači:
insert into stavkeotprzagorivo (istoceno) values (:old.naruceno);
PROMENIO BI SVE SLOGOVE U TABELI AKO TI SE U JEDNOM SLOGU POJAVI NELOGIČNOST!!! (pod uslovom da ovo može da se izvrši)

izmena: moja greška, mislio sam da je update, vali sve jedno ne valja, pukao bi insert...

Evo koda, nemam Oracle na ovom računaru sa kojeg pišem da bih isprobao...
Code:

CREATE OR REPLACE TRIGGER "istoceno" 
before insert or update of istoceno on stavkeotprzagorivo
For each row

begin 

if :new.istoceno > :new.naruceno then
   :new.istoceno := :new.naruceno;
  
end if;
end;

[ djoka_l @ 20.05.2009. 18:40 ] @
Accessing Column Values in Row Triggers

Within a trigger body of a row trigger, the PL/SQL code and SQL statements have access to the old and new column values of the current row affected by the triggering statement. Two correlation names exist for every column of the table being modified. There is one for the old column value and one for the new column value. These columns in the table are identified by :OLD.colum_name and :NEW.column_name. The use of :NEW and :OLD is shown in Example 6-1 and Example 6-2.

Depending on the type of triggering statement, certain correlation names might not have any meaning:

*

A trigger fired by an INSERT statement has meaningful access to new column values only. Because the row is being created by the INSERT operation, the old values are null.
*

A trigger fired by an UPDATE statement has access to both old and new column values for both BEFORE and AFTER row triggers.
*

A trigger fired by a DELETE statement has meaningful access to old (:OLD) column values only. Because the row no longer exists after the row is deleted, the new (:NEW) values are NULL and cannot be modified.

Old and new values are available in both BEFORE and AFTER row triggers. A new column value can be assigned in a BEFORE row trigger, but not in an AFTER row trigger (because the triggering statement takes effect before an AFTER row trigger is fired). If a BEFORE row trigger changes the value of NEW.column, then an AFTER row trigger fired by the same statement sees the change assigned by the BEFORE row trigger.

Correlation names can also be used in the Boolean expression of a WHEN clause. A colon (:) must precede the OLD and NEW qualifiers when they are used in a trigger body, but a colon is not allowed when using the qualifiers in the WHEN clause.


Do not create recursive triggers. For example, creating an AFTER UPDATE statement trigger on the employees table that will then issue an UPDATE statement on the same employees table, will cause the trigger to fire recursively until it has run out of memory.


[ Serbiankum @ 23.05.2009. 23:17 ] @
Da li u After trigeru ne moze da se koristi :new vrednost ?

Pokusao sam da od poslednjeg trigera napravim proceduru. Kod sam kompajlirao bez greske ali on ne radi. Gde bi bila greska?
Da li je jedini nacin testiranja procedure: BEGIN ime_procedure(vrednost); END; ili moze procedura nekako i drugacije da se testira bez pisanja koda?


Code:

CREATE OR REPLACE procedure naruceno

(istoceno out varchar2, naruceno in varchar2)

as
begin 

if istoceno > naruceno then
   istoceno := naruceno;
  
end if;
end;