0

メイン状態が 3 に更新されたときに selectoin allow を 1 に設定するトリガーを作成しようとしていますが、クエリを正しく機能させることができません。これまでのところ、私は持っています:

create table main
(main_id varchar(30) primary key,
name varchar(30) null,
state int null,
update_timestamp timestamp null);

create table selection 
(id varchar(30) primary key,
allow varchar(30) null,
last_update_timestamp timestamp null);

//
create trigger upd_selectoin 
before update on main 
for each row 
     IF new.state = 3 
     THEN 
   UPDATE selection s
    JOIN main m 
      ON m.main_id = s.id
     SET s.allow = 1
   WHERE s.id = NEW.main_id;
  END IF;
END;
//

insert into main values (1,'row1',1,null);
insert into main values (2,'row2',0,null);

insert into selection values (1,null,null);
insert into selection values (2,null,null);

エラーメッセージ:

スキーマの作成に失敗しました: SQL 構文にエラーがあります。near '// を使用する正しい構文については、MySQL サーバーのバージョンに対応するマニュアルを確認してください。

4

1 に答える 1

2

構文に少なくとも 2 つの問題があります。

  1. あなたは使うつもりだったDELIMITER //
  2. あなたが忘れてしまったBEGIN

正しい定義は次のようになります

DELIMITER // 
CREATE TRIGGER upd_selectoin 
BEFORE UPDATE ON main 
FOR EACH ROW 
BEGIN
  IF NEW.state = 3 THEN 
    UPDATE selection s JOIN main m 
        ON m.main_id = s.id
       SET s.allow = 1
     WHERE s.id = NEW.main_id; 
  END IF;
END //
DELIMITER ;

これがSQLFiddleのデモ です


今あなたの場合

  1. を更新する前に、 の更新が正常に行われたことを確認する代わりに、おそらくAFTEReventを使用することをお勧めします。BEFOREmainselection
  2. また、すでに知っているので、JOINselectionしても意味がありません。mainmain_id
  3. 以前に存在しなかった場合でもINSERT ... ON DUPLICATE KEY UPDATE、行が存在することを確認するために利用できますselection
  4. selectionおそらくその更新中にタイムスタンプを割り当てるつもりだったスキーマを見ると

つまり、トリガーのより簡潔なバージョンは次のようになります

CREATE TRIGGER upd_selection 
AFTER UPDATE ON main 
FOR EACH ROW 
  INSERT INTO selection (id, allow, last_update_timestamp)
  VALUES (NEW.main_id, IF(NEW.state = 3, 1, NULL), NOW())
  ON DUPLICATE KEY UPDATE allow = VALUES(allow), 
                          last_update_timestamp = VALUES(last_update_timestamp);

このバージョンのトリガーにはステートメントが 1 つしか含まれていないためDELIMITER、ブロックする必要さえありません。BEGIN ... END

これがSQLFiddleのデモです

于 2013-08-14T23:17:50.947 に答える