URLとそのパラメーターを表す文字列を含むテーブルがあります。問題は、URLとパラメータ文字列をテーブルの一意の制約にしたいことです。つまり、同じURLとパラメータ文字列を持つエントリはありません。パラメータ文字列は任意の長さにすることができます(MySqlキーの最大長である800バイトよりも長いため、エラーをスローするため、Unique(url、params)は使用できません...)。
トリガーを使用してこれを行うことを考えましたが、トリガーが挿入が重複エントリを挿入しようとしていることをトリガーが検出した場合、どのように例外をスローし、エラーを発生させますか? MySqlと同じようにMySqlExceptionがスローされるようにしたいのですが、C#コードでキャッチできます。
助けが必要なトリガーに2つの部分があります。.. C#に例外をスローする中止... C#に例外などをスローする方法を教えてください。 ...挿入を許可...-重複するエントリがない場合、どうすれば挿入を許可できますか?
トリガーコードは以下のとおりです。
CREATE TRIGGER urls_check_duplicates
BEFORE INSERT ON urls
FOR EACH ROW
BEGIN
DECLARE num_rows INTEGER;
SELECT COUNT(*)
INTO num_rows
FROM urls
WHERE url = NEW.url AND params = NEW.params;
IF num_rows > 0 THEN
... ABORT/throw exception to C# ...
ELSE
... Allow insert ...
END
トリガーに関するmysqlドキュメントのコメント は、mysqlにそのような機能がないことを示唆しています。あなたができる最善のことは、トリガーエラー用に別のテーブルを作成することです 同じページで提案されているように 。
私はこれに遭遇し、解決策は機能しますが、後でより良い解決策のように感じられるものに遭遇しました。この質問が最初に回答されたとき、これは選択肢ではなかったと思います。
CREATE TRIGGER `TestTable_SomeTrigger`
BEFORE UPDATE ON `test_table`
FOR EACH ROW
BEGIN
DECLARE msg VARCHAR(255);
IF (SomeTestToFail = "FAIL!") THEN
set msg = "DIE: You broke the rules... I will now Smite you, hold still...";
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
END IF;
-- Do any other code here you may want to occur if it's all OK or leave blank it will be
-- skipped if the above if is true
END$$
これにより、トラップできるNice(またはevil!)エラーメッセージが返されます。この詳細については、次を参照してください: http://dev.mysql.com/doc/refman/5.5/en/signal.html
これが他の誰かの役に立つことを願っています!
テーブル定義がNOT NULL値に対するものである場合、NEWをNULLに設定すると、事実上挿入が行われません。これを正しく機能させるには、厳密なSQLモードをオンにする必要がある場合があります。