web-dev-qa-db-fra.com

Avant insérer la gâchette dans mysql

Je suis nouveau à MySQL et j'ai des problèmes de création d'un déclencheur BEFORE INSERT.

Je reçois une erreur unexpected END.

J'ai une table nommée verlof_aanvragen avec une colonne datum (et 6 colonnes supplémentaires).

Ce que je veux accomplir n'est que des lignes avec une date entre now()+8 et now()+365 ou CURDATE() + INTERVAL 8 DAY AND CURDATE() + INTERVAL 365 DAY) peut être inséré. Un insert avec une date à l'extérieur de cet intervalle devrait échouer.

J'utilise la version 5.5.24 MySQL.

Ceci est le code:

CREATE TRIGGER chk_dates  
BEFORE INSERT ON verlof_aanvragen  
FOR EACH ROW  
BEGIN  
  IF (NEW.datum < CURDATE() + INTERVAL 8 DAY OR NEW.datum > CURDATE() + INTERVAL 365 DAY) 
THEN  
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Any Message'

END IF  
END 
4
Hans

J'ai traité cette question auparavant. MySQL a une architecture très fragile lorsqu'il s'agit de déclencheurs.

J'ai déjà écrit des postes avant de briser les déclencheurs médits. La solution est plutôt peu recommandée et laisserait un développeur PURE SQL avec un mauvais goût dans le mois.

Cela dit, voici mes postes que j'espère aiderait:

Depuis que vous êtes un débutant, le code de déclenchement d'écriture nécessite de modifier le délimiteur à autre chose qu'un point-virgule puis de la transformation.

DELIMITER $$

CREATE TRIGGER chk_dates  
BEFORE INSERT ON verlof_aanvragen  
FOR EACH ROW  
BEGIN  
  IF (NEW.datum < CURDATE() + INTERVAL 8 DAY OR NEW.datum > CURDATE() + INTERVAL 365 DAY) 
THEN  
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Any Message';
END IF;
END $$

DELIMITER ;

Veuillez regarder mes messages pour voir comment je fais cela dans mon code.

Mise à jour 2013-06-12 11:34 EDT

Voici votre dernier commentaire

J'utilise la gâchette ci-dessus avec MySQL Server V 5.5.24 et cela fonctionne bien. Ceci est mon site de test local. Maintenant, je veux l'utiliser sur monhost Webhost, ils ont MySQL Server V 5.1.56 ... et il a gagné; t Travailler! Est-ce que je manque quelque chose?

Le problème est la version mysql. Si vous regardez en arrière dans mes deux postes de déclenchement, j'ai utilisé des techniques de marché noir pour casser la gâchette médiane. Ceci est nécessaire pour les anciennes versions de MySQL. Remarquez ce que j'ai énoncé sur Apr 25, 2011 IN déclencheur dans MySQL pour prévenir l'insertion :

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).

Je cite directement les pages 254-256 de le livre

dlckxmd

Veuillez noter ce qui suit:

Par conséquent, Le traitement du signal ne fonctionne pas dans MySQL 5.1.

Vous devrez faire ce qui suit:

  • Réécrivez la gâchette dans MySQL 5.1 pour casser Midstream
  • Le déclencheur que vous avez écrit dans la base de données MySQL 5.5 devrait rester comme il est maintenant

C'est pourquoi le déclencheur ne fonctionne pas dans MySQL 5.1.

Mise à jour 2013-06-12 11:44 EDT

Voici ce que vous pouvez faire à la gâchette dans la base de données MySQL 5.1.56

DELIMITER $$

CREATE TRIGGER chk_dates  
BEFORE INSERT ON verlof_aanvragen  
FOR EACH ROW  
BEGIN  
  DECLARE dummy INT;
  IF (NEW.datum < CURDATE() + INTERVAL 8 DAY OR NEW.datum > CURDATE() + INTERVAL 365 DAY) 
THEN  
  SELECT 'Any Message' INTO dummy FROM mysql.user WHERE used = 'anything';
END IF;
END $$

DELIMITER ;

Depuis mysql.user n'a pas de colonne appelée used, la requête n'exécute pas, brisant la gâchette.

5
RolandoMySQLDBA