web-dev-qa-db-ja.com

MySQLのBEFORE INSERTトリガー

MySQLは初めてですが、_BEFORE INSERT_トリガーの作成に問題があります。

_unexpected END_エラーが発生します。

datum(さらに6列)を持つ_verlof_aanvragen_という名前のテーブルがあります。

私が達成したいのは、now()+8now()+365またはCURDATE() + INTERVAL 8 DAY AND CURDATE() + INTERVAL 365 DAY)の間の日付を持つ行のみを挿入できることです。その間隔外の日付の挿入は失敗するはずです。

MySQLバージョン5.5.24を使用しています。

これはコードです:

_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

私は以前にこの質問を扱いました。 MySQLは、トリガーに関しては非常に脆弱なアーキテクチャを持っています。

トリガーを途中で解除する方法については、以前に投稿しました。解決策はどちらかと言えば不快で、純粋なSQL開発者を今月は悪趣味にしてしまいます。

そうは言っても、これが私が助けてくれると期待する私の投稿です:

あなたは初心者なので、トリガーコードを作成するには、区切り文字をセミコロン以外のものに変更してから元に戻す必要があります。

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 ;

私のコードでこれをどのように行うかを確認するには、私の投稿を振り返ってください。

2013年6月12日11時34分EDT更新

これが最後のコメントです

上記のトリガーをMySQLサーバーv 5.5.24で使用していますが、正常に動作します。これは私のローカルテストサイトです。今私は私のウェブホストでそれを使いたいのですが、彼らはmysqlサーバーv 5.1.56を持っています...そしてそれは勝ちました; t仕事!何か不足していますか?

問題はMySQLのバージョンです。私の2つのトリガーポストを振り返ってみると、ブラックマーケットの手法を使用してトリガーを途中で打ち破りました。これは、古いバージョンのMySQLに必要です。 挿入を防ぐためにMySQLでトリガーApr 25, 2011について述べたことに注意してください。

この本がトリガーをこの方法でプリエンプトすることを提案する理由は、MySQLストアドプロシージャ言語がSIGNALを言語に実装していなかったという事実に由来します(もちろん、SIGNALはANSI標準です)。

この本の著者は、構文的には正しいが実行時に失敗するSQLステートメントを呼び出すことで回避策を作成しました。本の144〜145ページ(第6章:エラー処理)には、ストアドプロシージャを直接(例6-18)、またはSIGNALエミュレーション(例6-19および6-20)でプリエンプトする例が記載されています。

The Bookの254-256ページを直接引用しました

dlckxmd

次の点に注意してください:

したがって、信号処理はMySQL 5.1では機能しません。

次のことを行う必要があります。

  • MySQL 5.1のトリガーを書き直して、ミッドストリームを壊す
  • MySQL 5.5データベースに書き込んだトリガーは、現在の状態を維持する必要があります

そのため、MySQL 5.1ではトリガーが機能しません。

更新2013-06-12 11:44 EDT

これは、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 ;

mysql.userにはusedという列がないため、クエリは実行されず、トリガーが壊れます。

5
RolandoMySQLDBA