0

我正在尝试创建一个触发器,当主状态更新为 3 时,该触发器将 selectoin 允许设置为 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);

错误信息:

Schema Creation Failed:您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以获取在 '// 附近使用的正确语法

4

1 回答 1

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. 由于您已经知道,因此selection加入也没有任何意义。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);

这个版本的触发器甚至不需要DELIMITERBEGIN ... END阻塞,因为它只包含一个语句。

这是SQLFiddle演示

于 2013-08-14T23:17:50.947 回答