MySQL:使用触发器和IF语句更新第二个表

时间:2013-08-14 23:07:21

标签: mysql

我正在尝试创建一个触发器,当主状态更新为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);

错误讯息:

  

架构创建失败:您的SQL语法出错;校验   与您的MySQL服务器版本对应的手册   在'//

附近使用正确的语法

1 个答案:

答案 0 :(得分:2)

语法至少有两个问题:

  1. 您打算使用DELIMITER //
  2. 您忘记了BEGIN
  3. 正确的定义可能类似于

    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. 在对AFTER进行任何更新之前,您可能希望使用BEFORE事件而不是main来确保selection中的更新已成功完成。
    2. 由于您已经了解selection,因此main加入main_id也没有意义。
    3. 您可以利用INSERT ... ON DUPLICATE KEY UPDATE确保selection中的一行即使不存在,
    4. 查看selection架构,您可能需要在更新期间分配时间戳
    5. 据说,你的触发器的更简洁版可能看起来像

      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 演示