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

Before Insert Trigger

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von Vertax, 12 November 2010.

  1. Vertax

    Vertax Benutzer

    Hallo Community,
    ich habe mal eine Frage zur Trigger Programmierung:

    Aber erstmal vorab mein Tabellen aufbau:
    • Mitarbeiter (#PNr, Name, *ANr, Gehalt)
    • Abteilung (#ANr, AName)
    • Hotel (#HNr, HName, HKategorie, PLZ, Ort,Rahmenvertrag)
    • Reise (#*Mitarbeiter, #*Hotel, #Beginndatum, Dauer, Kosten)
    (#=Primärschlüssel, *=Fremdschlüssel)

    So meine Aufgabe ist folgende: Wenn ich in die Tabelle Reise ein neuen Datensatz eintragen möchte, soll erst überprüft werden ob das Hotel das eingetragen werden soll bei Rahmenvertrag eine 1 (also True) hat. Ansonst soll der Insert abgewiesen werden.

    Dies wollte ich mit einem Trigger realisieren mein momentaniger Ansatz ist:

    Code:
    delimiter //
    CREATE TRIGGER Rahmenvertrag_check BEFORE INSERT ON REISE
        FOR EACH ROW
        BEGIN
            /* IF CLAUSES */
        END;//
    delimiter ; 
    
    Somit hätte ich schonmal das Gerüst, ich stehe nun vor dem Problem wie ich die IF Abfrage des Rahmenvertrags realisiere, da diese ja das Attribut Rahmenvertrag in der Tabelle Hotel und nicht in Reisen habe.

    Hier muss ich wohl einen JOIN veranlassen, und wie ich dies in einem Trigger machen verstehe ich nicht.

    Ich hoffe ihr könnt mir weiter helfen.
     
  2. Vertax

    Vertax Benutzer

    AW: Before Insert Trigger

    sorry hab den bearbeiten button net gefunden.
    neuer ansatz:
    Code:
    delimiter //
    CREATE TRIGGER Rahmenvertrag_check1 BEFORE INSERT ON REISE
        FOR EACH ROW
        BEGIN
        
        Declare rv integer;
        
            Select Rahmenvertrag
            Into rv
            from Hotel
            JOIN REISE ON REISE.HOTEL = HOTEL.HNr
            where HNr=new.Hotel;
            
            
            IF rv = 1 THEN        
            Insert into Reise
            VALUES(new.Mitarbeiter,new.Hotel,new.Beginndatum,new.dauer,new.Kosten);
            END IF;
        END//
    delimiter ;
     
  3. Vertax

    Vertax Benutzer

    AW: Before Insert Trigger

    Also der Trigger macht jetzt das was er soll,ich weis nur nicht ob das ganze so sauber ist.

    Code:
    delimiter //
    CREATE TRIGGER Rahmenvertrag_check BEFORE INSERT ON REISE
        FOR EACH ROW
        BEGIN
        Declare rv integer;
        
            Select Rahmenvertrag
            Into rv
            from Hotel
            where HNr=new.Hotel;
            
            IF rv = false THEN        
            Insert into Reise
            VALUES(new.Mitarbeiter,new.Hotel,new.Beginndatum,new.dauer,new.Kosten);
            END IF;
        END//
    delimiter ;
    ich musste das rv=true in false ändern. Jetzt funktioniert der Trigger wie er soll.

    Bei einem Insert in Tabelle Reise werden nur die Hotels zugelassen die bei rahmenvertrag = true haben.

    Was ich nur nicht verstehe ist wieso hier false stehen muss?
    Ich wollte doch eigentlich prüfen ob rahmenvertrag = true ist und wenn das der fall ist darf er inserten, andernfalls nicht.

    Das macht er aber nur wenn ich rv = false schreibe. Weis einer wieso?

    Wenn ich jetzt z.b. ein Insert in die Tabelle Reise veranlasse und ein Hotel reinschreibe das bei Rahmenvetrag = false hat bekomme ich folgende Fehlermeldung und der Insert wird unterbrochen:

    Code:
    Error Code: 1442
    Can't update table 'reise' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
    Weitere Frage, wie kann ich eine eigene Fehlermeldung ausgeben lassen, so das da steht 'HOTEL HAT KEINEN RAHMENVERTRAG' oder sowas in der Art.
     
  4. thomas_w

    thomas_w Datenbank-Guru

    AW: Before Insert Trigger

    Besser wäre es, die Existens des Hotels mit COUNT(*) abzufragen. Treffermenge = 0 bedeutet nicht vorhanden.

    Der Trigger lautet ja auf BEFORE INSERT ON REISE, d.h. er wird automatisch aufgerufen, wenn ein INSERT auf die Tabelle REISE erfolgt. Innerhalb dem INSERT machst Du dann einen erneuten (TRIGGER-) INSERT, der dann den Trigger wieder aufruft etc. das ergibt dann eine Endlosschleife...

    Da bedeutet, Du müsstest eigentlich anders herum validieren...

    Code:
    [B]       IF rv  > 0 THEN   [/B]     
            --- EXCEPTION Stichwort MYSQL ERROR HANDLER
          END IF;
    
    Grüße
    Thomas
     
  5. Vertax

    Vertax Benutzer

    AW: Before Insert Trigger

    Diese Abfrage liefert mir aber doch so automatisch immer 1 und kann nie 0 werden. COUNT(*) zählt doch die Spalten und da ich definitiv immer einen Wert in der Spalterahmenvertrag habe true oder false kommt bei dieser Abfrage immer 1 heraus und nie 0.

    Wenn dann müsste ich doch ein and Rahmenvertrag hinzufügen, und wenn ich das so mache kann ich doch gleich auf den rahmenvertrag prüfen da dieser auch 0 oder 1 ist.
    Code:
    Select COUNT(*)
    from Hotel
    where HNr=6
    and Rahmenvertrag = true;
    
     
  6. thomas_w

    thomas_w Datenbank-Guru

    AW: Before Insert Trigger

    Okay, dann habe ich den Sinn der Spalte Rahmenvertrag falsch verstanden. Mir war nicht klar, dass Du einen Boolean-Wert in eine Integer-Variable einliest. Ohne Tabellenstruktur und Beispieldaten liegt man da eben gerne mal daneben.

    Aber ich denke, der Sinn meiner Abfrage ist Dir klar geworden. Insbesondere die Triggercascade, die ausgelöst wird.

    Grüße
    Thomas
     
Die Seite wird geladen...

Diese Seite empfehlen