1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  2. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

Frage zum insert/ update Trigger und Cursor

Dieses Thema im Forum "Oracle" wurde erstellt von Dirty, 19 Januar 2012.

  1. Dirty

    Dirty Neuer Benutzer

    Hallo zusammen,
    ich werkel jetzt schon den ganzen Tag an diesem Problem rum.
    Ich möchte bei jedem insert in meine Tabelle p_Spiel prüfen, ob der Schiedsrichter, welchen ich gerade (per FK) zuweise, auch zugelassen werden darf.
    Ok, hier mal mein Code:


    create or replace
    TRIGGER Trainer_Nationalität_Check
    BEFORE Insert or Update ON p_Spiel
    FOR EACH ROW
    declare
    -- Der cursor soll mir zum insert/ update in p_spiel die Länder holen, zu welchen die insert- Mannschaften gehören (Es sind immer 2: Mannschaft 1: Land, Mannschaft 2: Land):
    cursor ergebnismenge is
    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;

    schiri_land p_Land.land_name%type;


    BEGIN
    --Hier will ich die l.land_Name info des insert Schiri zwischenspeichern um sie unten im loop (im if) zu verarbeiten:
    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;

    for elem in ergebnismenge
    loop
    --if(elem.land_name = :new.)
    DBMS_OUTPUT.PUT_LINE (elem.land_name);
    end loop;
    EXCEPTION
    WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE (SQLERRM);
    END;


    Ich bin mir bewusst das FOR EACH ROW und der durchlauf mit dem Cursor nicht funktionieren und der Fehler "ORA-04091: Tabelle DABA11.P_SPIEL wird gerade geändert, Trigger/Funktion sieht dies möglicherweise nicht" kommt, weiß aber keinen anderen weg.

    Kann jemand helfen ?
     
  2. ukulele

    ukulele Datenbank-Guru

    Wann darf er denn nicht zugelassen werden, wenn er aus einem der Länder kommt die gegeneinander antreten?
    Wiso willst du das überhaupt mit einem Cursor machen und prüfst nicht einfach die beiden Mannschaften ab?
     
  3. Dirty

    Dirty Neuer Benutzer

    Hallo, ja. Also wenn der Schiri dem selben Land wie eines der beiden gegeneinander antretenden Mannschaften angehört, soll der insert abgebrochen werden.
    Aber du hast gesagt, dass ein Cursor nicht nötig sei (weißt du denn auch eine alternative lösung bei der Prüfung von insert- werten und einem Cursor?)


    Ohne Cursor kann ich mir folgendes vorstellen (habe aber Probleme bei der Umsetzung):

    Für die übersichtlichkeit hole ich mir erst das Land des zuzuweisenden Schiris und speichere es zwischen in 'schiri_land':

    schiri_land p_Land.land_name%type;
    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;


    Danach mache ich ein select, welches mir die zwei Länder der gegeneinander antretenden Mannschaften liefert
    und prüfe in der zurückgegeben Menge ob eines der beiden Länder gleich dem des Schiris ist. Ist es so, soll eine Exception raisen:


    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;

    ***
    In das SELECT darüber würde ich gerne eine IF- Klausel einbauen. Es klappt aber nie!
    ***

    Wie kann ich diesen Gedanken funktionsfähig umsetzen?
     
  4. ukulele

    ukulele Datenbank-Guru

    Das ist eigentlich schon richtig, ich skiziere es mal grob, habe grade kein SQL Server laufen:

    DECLARE @schiri_land VARCHAR(40) -- oder besser eine ID
    SET @schiri_land = ( SELECT schiri_land FROM whatevertablesbla )

    -- nur ein Weg wie man es machen könnte...
    IF EXISTS ( SELECT * FROM whatevertables WHERE team1_land = @schiri_land OR team2_land = @schiri_land )
    BEGIN
    EXCEPTION
    END
    -- natürlich kann man auch alle 3 Länder holen und dann prüfen, vieleicht bei unterschiedlichen Schreibweisen etc.




    Ich arbeite allerdings mit MSSQL, einige Sachen können Oracle spezifisch abweichen. Eine IF Abfrage kann eine besondere Tücke haben:
    IF a = b
    BEGIN
    SELECT 1
    END
    ELSE
    SELECT 2
    geht zwar, hat aber das problem das er ganzen Rest als ELSE Teil interpretiert. Das führt grade in Triggern häufig zu Fehlern. Besser ist:
    IF a = b
    BEGIN
    SELECT 1
    END
    ELSE
    BEGIN
    SELECT 2
    END
     
    PLSQL_SQL gefällt das.
Die Seite wird geladen...

Diese Seite empfehlen