Before Insert Trigger

Vertax

Benutzer
Beiträge
10
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.
 
Werbung:

Vertax

Benutzer
Beiträge
10
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 ;
 

Vertax

Benutzer
Beiträge
10
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.
 

thomas_w

SQL-Guru
Beiträge
104
AW: Before Insert Trigger

Code:
delimiter //
CREATE TRIGGER Rahmenvertrag_check BEFORE INSERT ON REISE
    FOR EACH ROW
    BEGIN
    Declare rv integer;
    
[B]        Select COUNT(*) AS rv[/B]
        Into rv
        from Hotel
        where HNr=new.Hotel;
        
[B]        IF rv = 0 THEN   [/B]     
         Insert into Reise
         VALUES(new.Mitarbeiter,new.Hotel,new.Beginndatum,new.dauer,new.Kosten);
        END IF;
    END//
delimiter ;
Das macht er aber nur wenn ich rv = false schreibe. Weis einer wieso?

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

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:
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
 

Vertax

Benutzer
Beiträge
10
AW: Before Insert Trigger

Code:
delimiter //
CREATE TRIGGER Rahmenvertrag_check BEFORE INSERT ON REISE
    FOR EACH ROW
    BEGIN
    Declare rv integer;
    
[B]        Select COUNT(*) AS rv[/B]
        Into rv
        from Hotel
        where HNr=new.Hotel;
        
[B]        IF rv = 0 THEN   [/B]     
         Insert into Reise
         VALUES(new.Mitarbeiter,new.Hotel,new.Beginndatum,new.dauer,new.Kosten);
        END IF;
    END//
delimiter ;
Besser wäre es, die Existens des Hotels mit COUNT(*) abzufragen. Treffermenge = 0 bedeutet nicht vorhanden.

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;
 
Werbung:

thomas_w

SQL-Guru
Beiträge
104
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

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
 
Oben