Announcement

Collapse
No announcement yet.

Before Insert Trigger

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

  • Before Insert Trigger

    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_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 ;

    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.
    Zuletzt editiert von Vertax; 12.11.2010, 22:17.

  • #2
    Du benötigst doch keinen JOIN ein Select nur auf Hotel reicht doch aus, die Bedingung dazu hast du bereits.
    Bei SQL-Code bitte beachten: Formatierung von SQL in Beiträgen

    Comment


    • #3
      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 = true THEN        
              Insert into Reise
              VALUES(new.Mitarbeiter,new.Hotel,new.Beginndatum,new.dauer,new.Kosten);
              END IF;
          END//
      delimiter ;
      Ju hast eigentlich recht, nur hab ich gerade ein Problem, mein Trigger funktioniert gerade verkehrt herum. Also er lässt die einträge zu wo Rahmenvertrag = 0 ist und nicht 1.

      Es sollte aber umgekehrt sein.

      Sieht jemand den Fehler?
      Zuletzt editiert von Vertax; 14.11.2010, 16:46.

      Comment


      • #4
        Den Abbruch eines Inserts in einem INSERT BEFORE TRIGGER ist nicht so einfach.
        Schau dir hierzu den Artikel "Emulating Check Constraints" an.

        http://forge.mysql.com/wiki/Triggers...ck_Constraints

        BTW. in einem INSERT TRIGGER ein Insert auszuführen ist auch irgendwie doppelt gemoppelt.
        Bei SQL-Code bitte beachten: Formatierung von SQL in Beiträgen

        Comment


        • #5
          Also der Trigger macht das was er soll,ich weis nur nicht ab das ganze so sauber ist.

          Nur wie gesagt er arbeitet gerade verkehrt herum, habe aber allerdings eben herausgefunden wie er richtig funktioniert:

          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.

          Comment


          • #6
            Was ich nur nicht verstehe ist wieso hier false stehen muss?
            Weil der Insert im Trigger nicht erlaubt ist und ein Fehler verursacht (ein Fehler im Trigger bricht den ganzen Insert-Vorgang ab).

            Weitere Frage, wie kann ich eine eigene Fehlermeldung ausgeben lassen, so das da steht 'HOTEL HAT KEINEN RAHMENVERTRAG' oder sowas in der Art.
            Siehe Link in meiner vorherigen Antwort.
            Bei SQL-Code bitte beachten: Formatierung von SQL in Beiträgen

            Comment


            • #7
              Danke, der Link war extrem hilfreich und lehreich zugleich.

              Und sorry das ich ihn mir nicht von anfang an durchgelesen habe ^^

              Comment

              Working...
              X