web-dev-qa-db-fra.com

Déclencheur dans MySQL pour empêcher l'insertion

Je souhaite créer la gâchette qui empêche l'insertion dans la table de réservation des vols (numflights) qui n'existe pas.

Tables
----------------------------------------------
flights(numflight, origine, destination, dep, arr)
airports(code, city, country)
reservation(people, numflight, date_travel)

Les colonnes origine et destination contiennent des codes de l'aéroport.

7
GameBuilder

L'exemple suivant est basé sur une méthode de piégeage des erreurs de trutée de Jerry dans les déclencheurs du chapitre 11, pages 254-256 du livre Programmation de la procédure stockée MySQL Sous la sous-position 'Validation des données avec des déclencheurs' :

DELIMITER $$

CREATE TRIGGER reservation_bi BEFORE INSERT ON reservation FOR EACH ROW
BEGIN

DECLARE found_count,dummy INT;

SELECT COUNT(1) INTO found_count FROM flights WHERE numflight=new.numflight;
IF found_count = 0 THEN
    SELECT 'Cannot Insert This Reservation Because Flight Number is Invalid'
    INTO dummy FROM reservation WHERE numflight=new.numflight;
END IF;

END; $$

DELIMITER ;

S'il y a une autre validation à faire, suivez cette même méthode de piégeage d'erreur !!!

METTRE À JOUR

La raison pour laquelle le livre suggère de préempter la gâchette de cette manière découle du fait que la langue de la procédure stockée MySQL n'avait pas de signal mis en œuvre dans la langue (bien sûr, signal est la norme ANSI).

Les auteurs du livre ont créé des contextes en appelant des déclarations SQL syntaxiquement, mais échouent au moment de l'exécution. Pages 144-145 (Chapitre 6: La manutention des erreurs) du livre donne ces exemples sur préempter une procédure stockée directement (exemple 6-18) ou par émulation de signal (exemples 6-19 et 6-20).

# Example 6-18. Using a nonexistent column name to force an error to the calling program

    CREATE PROCEDURE sp_update_employee_dob2
        (p_employee_id INT, p_dob DATE)
    BEGIN
        IF datediff(curdate(),p_dob)<(16*365) THEN
            UPDATE `Error: employee is too young; Employee must be 16 years or older`
                SET x=1;
        ELSE
            UPDATE employees
               SET date_of_birth=dob
            WHERE employee_id=p_dob;
       END IF;
    END;

# Example 6-19. Standard procedure to emulate SIGNAL

    CREATE PROCEDURE `my_signal`(in_errortext VARCHAR(255))
    BEGIN
        SET @sql=CONCAT('UPDATE `',in_errortext,'` SET x=1');
        PREPARE my_signal_stmt FROM @sql;
        EXECUTE my_signal_stmt;
        DEALLOCATE PREPARE my_signal_stmt;
    END;

# Example 6-20. Using our SIGNAL emulation procedure to raise an error

    CREATE PROCEDURE sp_update_employee_dob2
        (p_employee_id INT, p_dob DATE)
    BEGIN
        IF datediff(curdate(),p_dob)<(16*365) THEN
            CALL my_signal('Error: employee is too young; Employee must be 16 years or older')
        ELSE
            UPDATE employees
               SET date_of_birth=dob
            WHERE employee_id=p_dob;
       END IF;
    END;

Malheureusement, l'émulation du signal des exemples 6-19 et 6-20 ne peut pas être effectuée dans des déclencheurs. Les auteurs du livre ont utilisé la technique dans l'exemple 6-18 pour préempter les déclencheurs aux pages 254-256. C'est pourquoi la suggestion du livre doit être la voie à suivre.

4
RolandoMySQLDBA

Pourquoi ne pas simplement supprimer les droits d'insertion?

2
gbn