0

存在しないテーブルで挿入を実行することでエラーを「スロー」するinnodbエンジンを使用して、テーブルでトリガー前に挿入を正常に作成しました。問題は、本番サーバーでデータベース作成スクリプトを実行しようとすると、挿入テーブルが存在しないために失敗することです。ただし、同じスクリプトが私のワークステーションで正常に実行されるため、作成スクリプトが失敗する原因となっているMySQL構成設定があると思われます。

私の問題が提起する問題は、本番サーバーがトリガーをコンパイルしていて、ワークステーションがコンパイルしていない(または実行時にコンパイルしていない)かどうかです。実稼働環境では、作成時にSQLをコンパイルすることをお勧めします。

4

2 に答える 2

0

テーブル名の長さが問題の原因であることがわかりました。2つのサーバーバージョンは異なるリリースのものであり、サーバーは以前のリリース(5.0と5.1)でした。

トリガーでエラーを発生させることに関しては、私は別のアプローチを取りましたが、MySQLがcreatetriggerステートメントを処理する方法によっては欠陥がある可能性があります。トリガーステートメントが作成時に検証された場合、これは失敗します。

エラーが発生したら(予期されるエラー)、表示するエラーメッセージを含むセッション変数(変数名の前に@を付ける)を設定しました。エラーメッセージが設定されたら、存在しないテーブルDieに挿入して、MySQLでエラーを発生させます。

次に、アプリケーションはデータベースエラーをキャッチし、エラーセッション変数に対してクエリを実行します。結果に基づいて、エラーメッセージ、データベースエラーメッセージを含む例外をスローするか、クエリを静かに失敗させ、失敗したクエリを処理するための呼び出し元のコードを残します。

MySQLトリガー:

CREATE TRIGGER Error_Trigger 
BEFORE INSERT ON Fubar 
FOR EACH ROW
BEGIN
    if DataIsBad then
        set @Err = 'The data is fubared.';
        insert into Die values (1);                
    end if;    
END$$

アプリケーション側のコード:

public function getDatabaseErrorMessage($AdminMessage = false){
    if ($this->db->_error_number() != 0){
        $AdminError = $this->db->_error_message();
        $Query = $this->db->query("select @Err");
        if ($Query){
            $Error = $Query->row_array();
        }
        if (isset($Error["@Err"]) && $Error["@Err"] != ""){
            $Error = $Error["@Err"];
            $this->db->query("set @Err = ''");
        } else {
            if ($AdminMessage){
                $Error = $AdminError;
            } else {
                return false;
            }
        }
        throw new Exception($Error);
    }
}
于 2010-11-02T15:57:10.420 に答える
0

トリガーでエラーの発生をシミュレートするための私の方法はDECLARE、整数変数に文字列を格納することです。SQL_MODE =STRICT_ALL_TABLESの場合、エラーが発生します。それ以外の場合は、警告が発生します。

use test;

drop table if exists foo;
create table foo (id serial primary key, bar varchar(10));

drop trigger if exists RaiseError;

delimiter //

create trigger RaiseError before insert on foo
for each row
begin
  declare bar int;
  if new.bar = 'boom' then
    set bar = 'You cannot store that value!';
  end if;
end //

delimiter ;

set sql_mode = strict_all_tables;

insert into foo (bar) values ('boom');

テストする列バーと同じ名前をローカル変数に付けたことに注意してください。そうすれば、変数の名前がエラー メッセージに表示されます。これは列と同じです。

エラー 1366 (HY000): 整数値が正しくありません: 「その値を保存できません!」行 1 の列 'bar' の場合

于 2010-09-03T02:02:47.260 に答える