[ Raaaa @ 27.03.2010. 14:22 ] @
Ovako treba da napravim proceduru i trigger koji ce da odrade sumiranje svih troskova u tabeli stavka troskova koja je slab objekat od troskova registracije i da ih prikaze u polju ukupno koje se nalazi u tabeli troskovi registracije medjutim uvek mi kasni jedan korak tj. tek kad unesem novu stavku azurira mi prethodne u tabeli(bez nove unete) mucim se sa tim ne mogu da resim a pretpostavljam da je neka sitnica u pitanju. Radim u apexu a evo tabela i procedura i triggera:

Code:

PROCEDURA:

CREATE OR REPLACE PROCEDURE INSERT_UKUPNO(P_SIFRA_TROSKOVA IN TROSKOVI_REGISTRACIJE.SIFRA_TROSKOVA%TYPE,
P_UKUPNO IN TROSKOVI_REGISTRACIJE.UKUPNO%TYPE) AS
BEGIN
UPDATE TROSKOVI_REGISTRACIJE SET
UKUPNO=P_UKUPNO
WHERE SIFRA_TROSKOVA = P_SIFRA_TROSKOVA;
END INSERT_UKUPNO;
/


TRIGGER:

CREATE OR REPLACE TRIGGER  "UKUPNO_RACUNA_TR" 
before INSERT ON STAVKA_TROSKOVA
FOR EACH ROW
DECLARE
L_UKUPNO TROSKOVI_REGISTRACIJE.UKUPNO%TYPE;
BEGIN
SELECT SUM(IZNOS_U_DINARIMA)INTO L_UKUPNO FROM STAVKA_TROSKOVA
WHERE STAVKA_TROSKOVA.SIFRA_TROSKOVA= :NEW.SIFRA_TROSKOVA;
INSERT_UKUPNO(:NEW.SIFRA_TROSKOVA, L_UKUPNO);
END;

TABELE:

CREATE TABLE  "TROSKOVI_REGISTRACIJE" 
   (    "SIFRA_TROSKOVA" VARCHAR2(20) NOT NULL ENABLE, 
    "UKUPNO" NUMBER, 
     CONSTRAINT "TROSKOVI_REGISTRACIJE_PK" PRIMARY KEY ("SIFRA_TROSKOVA") ENABLE
   )
/


CREATE TABLE  "STAVKA_TROSKOVA" 
   (    "SIFRA_TROSKOVA" VARCHAR2(20) NOT NULL ENABLE, 
    "REDNI_BROJ" VARCHAR2(20) NOT NULL ENABLE, 
    "IZNOS_U_DINARIMA" NUMBER, 
    "PRIMAOC" VARCHAR2(20), 
    "UPLATNI_RACUN" VARCHAR2(20), 
     CONSTRAINT "STAVKA_TROSKOVA_PK" PRIMARY KEY ("SIFRA_TROSKOVA", "REDNI_BROJ") ENABLE, 
     CONSTRAINT "STAVKA_TROSKOVA_FK" FOREIGN KEY ("SIFRA_TROSKOVA")
      REFERENCES  "TROSKOVI_REGISTRACIJE" ("SIFRA_TROSKOVA") ENABLE
   )
/



Unapred hvala za pomoc

[ djoka_l @ 27.03.2010. 17:43 ] @
Prvo, grešiš to što je triger BEFORE INSERT, a treba AFTER INSERT. Računaš sumu, a poslednji slog još nije upisan.

Drugo, konceptualna greška je što u trigeru računaš sumu. Ako u tabelu STAVKA_TROSKOVA insertuješ 1000 slogova, svaki put ćeš da računaš sumu, prvo 1 sloga, pa 2,3, ... 999, 1000, umesto samo da ažuriraš slog u TROSKOVI_REGISTRACIJE vrednošću :new.vrednost_u_dinarima.

Code (plsql):

CREATE OR REPLACE TRIGGER  "UKUPNO_RACUNA_TR"
after INSERT ON STAVKA_TROSKOVA
FOR EACH ROW

BEGIN
  UPDATE troskovi_registracije
  SET ukupno = NVL(ukupno) + :NEW.vrednost u dinarima
  WHERE sifra_troskova = :NEW.sifra_troskova;

END;
 
[ Raaaa @ 27.03.2010. 18:56 ] @
Citat:
djoka_l: Prvo, grešiš to što je triger BEFORE INSERT, a treba AFTER INSERT. Računaš sumu, a poslednji slog još nije upisan.

Drugo, konceptualna greška je što u trigeru računaš sumu. Ako u tabelu STAVKA_TROSKOVA insertuješ 1000 slogova, svaki put ćeš da računaš sumu, prvo 1 sloga, pa 2,3, ... 999, 1000, umesto samo da ažuriraš slog u TROSKOVI_REGISTRACIJE vrednošću :new.vrednost_u_dinarima.

Code (plsql):

CREATE OR REPLACE TRIGGER  "UKUPNO_RACUNA_TR"
after INSERT ON STAVKA_TROSKOVA
FOR EACH ROW

BEGIN
  UPDATE troskovi_registracije
  SET ukupno = NVL(ukupno) + :NEW.vrednost u dinarima
  WHERE sifra_troskova = :NEW.sifra_troskova;

END;
 


Kao prvo hvala na odgovoru nisam razmisljao o ovoj konceptualnoj gresci ipak je to veliki propust jer mi je zadatak optimizacija baze svaka cast nisam se toga setio... Bacao mi je gresku kad stavim AFTER INSERT TRIGGER MUTATING... ali sa ovim tvojim kodom sve radi kako treba e sad postoji jos jedna stvar a to je da ja imam zahtev da preko procedure resim ovo a trigger samo da je poziva :( veoma sam zelen u ovoj oblasti tako da mi je sve jos uvek konfuzno :(... i kako da resim kad mi se obrise stavka da se azurira i u tabeli troskovi_registracije?

Unapred hvala,

Pozdrav
[ djoka_l @ 27.03.2010. 21:18 ] @
Napravi trigger after insert or delete, na primer

Code (plsql):

CREATE OR REPLACE TRIGGER ins_del_stavke
after INSERT OR DELETE OR UPDATE ON stavka_troskova

BEGIN

  IF inserting THEN pozovi_proceduru1(:NEW.sifra_troskova, :NEW.vrednost_u_dinarima); END IF;
  IF deleting THEN pozovi_proceduru2(:old.sifra_troskova, :old.vrednost_u_dinarima); END IF;
  IF updating THEN pozovi_proceduru3(:old.sifra_troska, :old.vrednost_u_dinarima, :NEW.vrednost_u_dinarima); END IF;

END;
 

[ Raaaa @ 28.03.2010. 19:26 ] @
Hvala na pomoci :) POkusacu ovo da odradim sad mi je jasnije mislim da nece biti problema
[ Raaaa @ 28.03.2010. 20:27 ] @
Ipak ima problema :)

Code (plsql):
CREATE OR REPLACE PROCEDURE UPDATE_UKUPNO(P_SIFRA_TROSKOVA IN STAVKA_TROSKOVA.SIFRA_TROSKOVA%TYPE,
P_UKUPNO IN TROSKOVI_REGISTRACIJE.UKUPNO%TYPE,
P_IZNOS_U_DINARIMA IN STAVKA_TROSKOVA.IZNOS_U_DINARIMA%TYPE) AS
BEGIN
UPDATE troskovi_registracije
  SET P_ukupno = NVL(P_ukupno,0) + P_iznos_u_dinarima
  WHERE sifra_troskova = P_sifra_troskova;

END UPDATE_UKUPNO;
/


Kad ovaj kod stavim u proceduru vraca mi gresku ERROR at line 6: PL/SQL: ORA-01733: virtual column not allowed here

[Ovu poruku je menjao misk0 dana 01.04.2010. u 17:20 GMT+1]
[ djoka_l @ 29.03.2010. 11:33 ] @
I dalje mi nije jasno zašto je potrebno pisati proceduru za jedan UPDATE koji može da se stavi u trigger.
U svakom slučaju, ako i dalje insistiraš prvo proveri da li je tabela koju ažuriraš stvarno tabela i pogled (view), jer se ova greška (-1733) pojavljuje kada se pokuša ažuriranje kolene u pogledu koja nije polje nego izračunata vrednost.

Ako problem prave parametri kojim je pozvana procedura (:new, odnosno :old parametri), probaj da deklarišeš lokalne varijable u triggeru, pa onda njih da preneseš umesto onoga što sada stoji.

I još jedno pitanje: ZAŠTO PISATI PROCEDURU ZA JEDAN UPDATE ???
[ Raaaa @ 29.03.2010. 11:47 ] @
:) Takav je zahtev profesora, njegova zamisao je kao da procedura sracuna sve stavke a trigger da azurira ukupno zbog optimizacije a ovo resenje koje si mi ti dao preko triggera radi odlicno
[ darkosos @ 01.04.2010. 14:27 ] @
problem je u

SET P_ukupno = NVL(P_ukupno,0) + P_iznos_u_dinarima

tu treba da setoji polje iz tabele.
[ Raaaa @ 02.04.2010. 16:38 ] @
Uspeo sam da resim :)

Evo koda

Code (plsql):
CREATE OR REPLACE PROCEDURE troskovi_UKUPNO(

  L_SIFRA_TROSKOVA IN TROSKOVI_REGISTRACIJE.SIFRA_TROSKOVA%TYPE,
  L_ukupno IN TROSKOVI_REGISTRACIJE.UKUPNO%TYPE,
  L_IZNOS_U_DINARIMA IN stavka_TROSKOVA.IZNOS_U_DINARIMA%TYPE,
  L_ukupno_TROSKOVI OUT TROSKOVI_REGISTRACIJE.ukupno%TYPE)AS

BEGIN
  L_UKUPNO_TROSKOVI :=  L_ukupno + L_IZNOS_U_DINARIMA;
UPDATE  TROSKOVI_REGISTRACIJE SET
ukupno=   L_UKUPNO_TROSKOVI
WHERE SIFRA_TROSKOVA=L_SIFRA_TROSKOVA;
END troskovi_UKUPNO;



CREATE OR REPLACE TRIGGER  "RACUNA_UKUPNO"
AFTER INSERT ON STAVKA_TROSKOVA
FOR EACH ROW
DECLARE

  l_SIFRA_TROSKOVA TROSKOVI_REGISTRACIJE.SIFRA_TROSKOVA%TYPE;
  l_ukupno TROSKOVI_REGISTRACIJE.UKUPNO%TYPE;
  l_IZNOS_U_DINARIMA stavka_TROSKOVA.IZNOS_U_DINARIMA%TYPE;
  L_ukupno_TROSKOVI TROSKOVI_REGISTRACIJE.ukupno%TYPE;

BEGIN
l_SIFRA_TROSKOVA := :NEW.SIFRA_TROSKOVA;
l_IZNOS_U_DINARIMA := :NEW.IZNOS_U_DINARIMA;

SELECT UKUPNO INTO l_ukupno FROM TROSKOVI_REGISTRACIJE
WHERE SIFRA_TROSKOVA = l_SIFRA_TROSKOVA;
troskovi_UKUPNO(l_SIFRA_TROSKOVA, L_ukupno,  L_IZNOS_U_DINARIMA,  L_ukupno_TROSKOVI);
END;
 


[Ovu poruku je menjao misk0 dana 02.04.2010. u 21:42 GMT+1]
[ trigeriprocedura @ 14.01.2011. 20:39 ] @
Koji je najlaksi nacin da se nauce trigeri i procedire. Neophodno mi je to da naucim u sto kracem vremenskom roku zbog polaganja ispita. Ako neko ima dobru dokumenaciju neka mi posalje na mail ili ako dobro poznaje materiju i raspolozen je da mi pomogne neka mi se javi ma mail [email protected] Unaprijed zahvalna!