web-dev-qa-db-fra.com

Comment faire un déclencheur qui comparera l'entrée avec une valeur d'une autre table?

J'avais fait deux tables avec les champs suivants:

TABLE 1: "Bookings"
  FIELD: "fk_flight_number"
  FIELD: "date_of_reservation"    

TABLE 2: "Flights"
  FIELD: "flight_number"
  FIELD: "date_of_departure"

Je veux ajouter une condition, juste pour la consistance de mes données. Je veux vérifier sur INSERT:

1) Dans Bookings - fk_flight_number doit exister en Flights

2) date_of_reservation doit être plus petit (<) de date_of_departure.

Comment faire ça? J'ai lu quelque chose de similaire et le mot clé déclenchait. Je pense que dans mon cas, il doit être pareil. Pouvez-vous me montrer comment référer la deuxième table? Les conditions logiques ne sont pas importantes - je peux le gérer. J'ai besoin d'un petit extrait, car je ne sais pas comment commencer à écrire la gâchette dont j'ai besoin. Ou si vous connaissez un article décrivant un problème similaire - je l'apprécierai aussi. Merci beaucoup. De cource Je ne suis pas sûr à 100% que la meilleure approche soit déclenchée. Tout autre conseil sera également apprécié. Une fois de plus - merci!

3
Don Angelo Annoni
DELIMITER $$  
CREATE TRIGGER Bookings_BeforeInsert BEFORE INSERT ON Bookings
FOR EACH ROW  
BEGIN  
    DECLARE found_flight,dummy,baddata INT;
    DECLARE dt DATETIME;
    SET baddata = 1;
    SELECT COUNT(1) INTO found_flight FROM Flights
    WHERE flight_number = NEW.fk_flight_number;
    IF found_flight > 0 THEN
        SELECT date_of_departure INTO dt FROM Flights
        WHERE flight_number = NEW.fk_flight_number;
        IF date_of_reservation < date_of_departure THEN
            SET baddata = 0;
        END IF;
    END IF;
    IF baddata = 1 THEN  
        SELECT CONCAT('Cannot Insert This Because Age ',NEW.age,' is Invalid')  
        INTO dummy FROM information_schema.tables;
    END IF;  
END; $$  
DELIMITER ;

La déclaration IF IF baddata = 1 THEN a été fait un faux message exprès. C'est parce que la gestion des erreurs MySQL pour les procédures stockées n'est pas conçue correctement. Cette solution de contournement folle que j'ai reçue des pages 254-256 du livre Programmation de procédure stockée MySQL

enter image description here

sous la sous-position "Validation des données avec des déclencheurs":

J'ai écrit sur ce style de programmation de déclenchement dans mes postes antérieurs

1
RolandoMySQLDBA

Réponse SQL Server

CREATE TRIGGER FightNumberExists ON dbo.Bookings
AFTER INSERT
AS
IF EXISTS (SELECT fk_flight_number
           FROM inserted i
           INNER JOIN Flights f 
              ON f.flight_number = i.fk_flight_number
           WHERE i.date_of_reservation < f.date_of_departure   
      )
BEGIN
    RAISERROR ('Flight Number does not exist', 16, 1);
    ROLLBACK TRANSACTION;

    RETURN 
END;

GO

Notes Dans SQL Server, les valeurs sont d'abord chargées dans la table "insérée" ou "supprimée" avant d'être écrite sur la table physique.

Vous pouvez également y accomplir avec l'ajout de contraintes aux tables.

1
Craig Nicholson