Announcement

Collapse
No announcement yet.

Frage zum Trigger + Select Statement

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Frage zum Trigger + Select Statement

    Hallo zusammen,
    ich habe folgendes vor und brauche Hilfe:
    Dieses ist mein Trigger:


    Code:
    create or replace
    TRIGGER Trainer_Nationalität_Check
    BEFORE Insert or Update ON p_Spiel
    FOR EACH ROW
    declare
      schiri_land p_Land.land_name%type;
    begin
      --Schir Land:
      select l.land_name into schiri_land from p_schiedsrichter s
        join p_stammt_von3 sv3 on sv3.schiedsrichter_id = s.schiedsrichter_id
          join p_land l on l.land_name = sv3.land_name and s.schiedsrichter_id = :new.hauptschiedsrichter_id;
      DBMS_OUTPUT.PUT_LINE ('Herkunft: '||schiri_land);
      
      -- M1 & M2 Land + CASE:
      select l.land_name from p_spiel s
        join p_antreten_gehort_zu agz on agz.spiel_id = s.spiel_id and s.spiel_id = :new.spiel_id
          join p_mannschaftsaufstellung ma on ma.mannschaftsaufstellungs_id = agz.mannschaftsaufstellungs_id
            join p_mannschaft m on m.mannschaft_name = ma.mannschaft_name
              join p_land l on l.mannschaft_name = m.mannschaft_name order by s.spiel_id;
    
    EXCEPTION
      WHEN OTHERS THEN
      		DBMS_OUTPUT.PUT_LINE (SQLERRM);  
    end;

    Er soll folgendes tun: Erst hole ich mir das Land eines Schiris und speichere es in einer Variable zwischen.
    Danach (im zweiten SELECT darunter) hole ich mir die Länder der beiden gegeneinander antretenden Mannschaften. Ist nur eines der beiden Länder der Mannschaften identisch mit dem des Schiris, soll das insert abgebrochen werden. Das habe ich mir so vorgestellt:


    Code:
    select 
      case when l.land_name = schiri_land then raise_application_error (-20001, 'Identische Länder!.') else DBMS_OUTPUT.PUT_LINE ('Alles ok') end
      from p_spiel s
        join p_antreten_gehort_zu agz on agz.spiel_id = s.spiel_id and s.spiel_id = :new.spiel_id
          join p_mannschaftsaufstellung ma on ma.mannschaftsaufstellungs_id = agz.mannschaftsaufstellungs_id
            join p_mannschaft m on m.mannschaft_name = ma.mannschaft_name
              join p_land l on l.mannschaft_name = m.mannschaft_name order by s.spiel_id;

    Leider funktioniert das so nicht und ich bekomme immer diese Meldung:
    TRIGGER Trainer_Nationalität_Check kompiliert
    Warning: Ausführung mit Warnung abgeschlossen


    Hat jemand eine Idee woran es hängt?
    Grüße

  • #2
    Eine etwas genauere Lösungsidee

    Hallo, auch wenn noch niemand geantwortet hat oder das selbe Problem haben sollte, habe ich einen zweiten Lösungsansatz gefunden der die Sache zwar nicht löst aber der Lösung evtl. näher kommt.
    Ich brauche nach wie vor Hilfe bei der Umsetzung, da sich der Trigger zwar kompilieren (ohne Warnung) lässt aber bei dessen Ausführung folgender Fehler kommt:

    ORA-04091: Tabelle DABA11.P_SPIEL wird gerade geändert, Trigger/Funktion sieht dies möglicherweise nicht.

    Es hängt scheinbar an den SELECTS, wo ich die Werte in land_1 und land_2 packe.

    Also, hier nochmal mein Statement:
    Code:
    create or replace
    TRIGGER Trainer_Nationalität_Check
    BEFORE Insert or Update ON p_Spiel
    FOR EACH ROW
    declare
      schiri_land p_Land.land_name%type;
    
      land_1 p_Land.land_name%type;
      land_2 p_Land.land_name%type;
    begin
      --Das Land des Schiris finden und zwischen speichern:
      select l.land_name into schiri_land from p_schiedsrichter s
        join p_stammt_von3 sv3 on sv3.schiedsrichter_id = s.schiedsrichter_id
          join p_land l on l.land_name = sv3.land_name and s.schiedsrichter_id = :new.hauptschiedsrichter_id; 
      
      
    --Das Land der Mannschaft 1 finden und zwischen speichern:
        select land_name into land_1 from(
        select l.land_name from p_spiel s
        join p_antreten_gehort_zu agz on agz.spiel_id = :new.spiel_id
          join p_mannschaftsaufstellung ma on ma.mannschaftsaufstellungs_id = agz.mannschaftsaufstellungs_id
            join p_mannschaft m on m.mannschaft_name = ma.mannschaft_name
              join p_land l on l.mannschaft_name = m.mannschaft_name order by s.spiel_id) where rownum = 1;
      
    --Das Land der Mannschaft 2 finden und zwischen speichern:
        select land_name into land_2 from(
        select l.land_name from p_spiel s
        join p_antreten_gehort_zu agz on agz.spiel_id = :new.spiel_id
          join p_mannschaftsaufstellung ma on ma.mannschaftsaufstellungs_id = agz.mannschaftsaufstellungs_id
            join p_mannschaft m on m.mannschaft_name = ma.mannschaft_name
              join p_land l on l.mannschaft_name = m.mannschaft_name order by s.spiel_id) where rownum = 2;   
    
    --Prüfen, ob Schiri-Land = Mannschaft 1, 2 Land
        if land_1 = schiri_land or land_2 = schiri_land then
    --Falls das so ist, insert abbrechen
          raise_application_error (-20001, 'Fehler: Land Schiri = Mannschaftsland.');
        end if;
    
    DBMS_OUTPUT.PUT_LINE ('Herkunft Schiri: '||schiri_land);
    DBMS_OUTPUT.PUT_LINE ('M1: '||land_1);
    DBMS_OUTPUT.PUT_LINE ('M2: '||land_2);
    EXCEPTION
      WHEN OTHERS THEN
      		DBMS_OUTPUT.PUT_LINE (SQLERRM);  
    end;
    Kann jemand helfen?

    Comment


    • #3
      Das ist ein typisches "mutating table" Problem, es gibt viele Hinweise dazu hier im Forum oder im Web, z.B. hier oder bei AskTom.

      Comment


      • #4
        Originally posted by jum View Post
        Das ist ein typisches "mutating table" Problem, es gibt viele Hinweise dazu hier im Forum oder im Web, z.B. hier oder bei AskTom.
        Seit Oracle 11 gibt es die sog. "Compound Trigger". Damit kannst du alles in einen Trigger packen ohne das ganze Drumherum mit der temporären Tabelle oder einem Package in dem du Variablen ablegst.

        Die saubere Variante wäre aber sicher eine PL/SQL Prozedur die das alles erledigt.

        Gruss

        Comment

        Working...
        X