[PL/SQL] Trigger ignoriert "Exception when others then"

DerAskTyp

Mitglied
Servus Ich habe diesen Trigger hier:

SQL:
create or replace TRIGGER T_MINDESTLAGERMENGE
BEFORE INSERT OR UPDATE ON ET_LISTE
for each row
declare
lagermenge number := 0;
minlagermenge number := 0;
menge_et number :=0;
BEGIN
  select count(*) into menge_et from lager where lager.a_nr = :new.et_nr;
  if menge_et = 0 then
      raise_application_error(-20222, 'Artikel nicht gefunden. Es wurde nachbestellt');
  end if;
 
 
  select lager.lagermenge into lagermenge from lager where :new.et_nr = lager.a_nr;
  select lager.mindestlagermenge into minlagermenge from lager where :new.et_nr = lager.a_nr;

  if (lagermenge - :new.et_menge) < 0 then
      raise_application_error(-20111, 'Nachbestellung IST NICHT MÖGLICH! bei art:' || :new.et_nr);
  elsif (lagermenge - :new.et_menge) < minlagermenge  then
        DBMS_OUTPUT.PUT_LINE('trigger funktioniert');
    raise_application_error(-20222, 'minmenge unterschritten. Es wurde nachbestellt');
  end if;
END;

Hier ist meine Procedure:
SQL:
create or replace procedure bestellen (anr varchar2, bmenge number) as

Procedure ermittle_einzelteile( anr  varchar2, emenge number) ; --Prototyp
Procedure p_privatenachbestellung( anr  varchar2, msg varchar2) ; --Prototyp
Procedure p_nbmenge_zulageradden; --Prototyp


Procedure ermittle_einzelteile( anr varchar2, emenge number) as
Cursor c1 is select * from struktur where o_a_nr = anr;
c1_rec c1%ROWTYPE;
Flag number:=0;
menge_neu number :=0;
curSeq number :=0; /*sowie id.*/
lm number:=0;

Begin
    Flag := 0;
    For c1_rec in C1 loop
        Flag := 1;
          menge_neu := emenge*c1_rec.menge;
        Ermittle_einzelteile(c1_rec.u_a_nr, menge_neu);
    End loop;
    If Flag = 0 then
    begin
      curSeq  := ETAUFTRAGSEQUENCE.currVal;
      insert into et_liste values(curSeq, anr, emenge);
      select lager.lagermenge  into lm from lager where a_nr = anr;
      update lager set lagermenge = lagermenge-emenge where a_nr = anr;
      exception when others then
        DBMS_OUTPUT.PUT_LINE('bin in excepion when others then');
        if SQLCODE != -20222 then  /*genug im lager und existiert*/
          if SQLCODE = -20111 then
            raise_application_error(-20000,'nachbs. nit mögl. lager von:' || anr || ' ist ' || lm || 'aber neue menge is größer' || emenge);
          else
            update et_liste set et_menge = et_menge + emenge where et_nr = anr and pa_nr = curSeq;
            update lager set lagermenge = lagermenge-emenge where a_nr = anr;   
          end if;
        else
              DBMS_OUTPUT.PUT_LINE('ich sollte hier sein');
            p_privatenachbestellung(anr, substr(SQLERRM, 1, 65));
        end if;   
   end;
    End if;
End;

Procedure p_privatenachbestellung(anr varchar2, msg varchar2) as
begin
  /*ROLLBACK; *//*allle gespeichertden et daten weerden zrckgestellt, weil pauftrag nicht valide is(zu gringe menge)*/
  begin
    DBMS_OUTPUT.PUT_LINE(msg);
    insert into nachbestellen values(anr);
    DBMS_OUTPUT.PUT_LINE(anr || ' nachbestellt');
    exception when others then
      DBMS_OUTPUT.PUT_LINE('Artikel ' || anr || ' wurde bereits nachbestellt');
    end;
    commit;
end;

/*wird nachdem man in nachbestelltabelle eingefügt hat aufgerufen*/
Procedure p_nbmenge_zulageradden AS
Cursor cl is select a_nr from nachbestellen;
cl_rec cl%ROWTYPE;
menge number := 0;
BEGIN
  For cl_rec in Cl loop
    begin
      insert into lager values(cl_rec.a_nr, 10, 5, 10, null);
      exception when others then
        update lager set lagermenge = lagermenge + nachbestellmenge where a_nr = cl_rec.a_nr;
    end;
  end loop;
END;


Begin
  insert into produktionsauftrag values(ETAUFTRAGSEQUENCE.nextVal, anr, bmenge);
    Ermittle_einzelteile(anr,bmenge);
 
  p_nbmenge_zulageradden();
  delete from nachbestellen;/*nachbestellen daten für den derzeitgen auftrag löschen, weil ja lager upgedated wird*/
 
  DBMS_OUTPUT.PUT_LINE('Success Produktionsauftrag ist geschafft');
    commit;
Exception
    When others then
    DBMS_OUTPUT.PUT_LINE('pauftrag failed. error:' || substr(SQLERRM, 1, 65));
        Rollback;
End;


Das wichtige ist eigentlich nur die "exception when others then" in der Procedure "ermittle_einzelteile"

Das Problem ist es, dass wenn der Trigger aktiviert wird, er eigentlich die "exception when others then" in der prozedur "ermittle_einzelteile" ignoriert und direkt die äußere Prozedur (bestellen) benachrichtigt.

Als Übersicht habe ich wie Sie sehen können immer eine Ausgabe in der Konsole gemacht. Das ist z.b das Ergebnis, wenn die Prozedur aufgerufen wird:


bin in excepion when others then
trigger funktioniert
pauftrag failed. error:ORA-20222: minmenge unterschritten. Es wurde nachbestellt
ORA-065

Wie sie sehen können funktioniert irgendwie anscheinend die if anweisung in "exception when others then" nicht (if SQLCODE.....)


Die Prozedur kommt immer in die Anweisugn rein: if(SQLCODE !=-20222). Dort habe ich
DBMS_OUTPUT.PUT_LINE(SQLCODE); gemacht und bekomme -1 zurück.
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück