2017-03-16 156 views
1

我检查了很多SO线程(one of them here),但找不到问题出在哪里。mysql创建触发器语法错误

我试图保护列不被更新,如果它不为空,请遵循this thread

但我从mysql获取语法错误。这里是我的代码:

DELIMITER $$ 

CREATE TRIGGER lock_x_id 
BEFORE UPDATE ON Games 
FOR EACH ROW BEGIN 
    IF (old.xid IS NOT NULL) THEN 
    SIGNAL 'error'; 
    END IF; 
END$$ 

DELIMITER ; 
+0

什么是错误? –

+0

错误1064(42000):您的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册,以找到在'error'附近使用的正确语法; –

回答

2

当您尝试通过SIGNAL筹集错误,你需要指定SQLSTATE这是错误代码和用户定义的通用错误代码,其45000随着消息文本MESSAGE_TEXT

因此,触发随着

delimiter // 
create trigger lock_x_id before update on games 
for each row 
begin 
if old.xid is not null then 
    signal SQLSTATE VALUE '45000' SET MESSAGE_TEXT = 'Your custom error message'; 
end if; 
end;// 
delimiter ; 

测试用例

mysql> select * from games; 
+----+------+------+ 
| id | xid | val | 
+----+------+------+ 
| 1 | NULL | 1 | 
| 2 | NULL | 2 | 
| 3 | NULL | 3 | 
| 4 | 1 | 4 | 
| 5 | 2 | 5 | 
+----+------+------+ 

让我们创建触发器现在

mysql> delimiter // 
mysql> create trigger lock_x_id before update on games 
    -> for each row 
    -> begin 
    -> if old.xid is not null then 
    -> signal SQLSTATE VALUE '45000' SET MESSAGE_TEXT = 'Your custom error message'; 
    -> end if; 
    -> end;// 
Query OK, 0 rows affected (0.05 sec) 


mysql> update games set xid = 4 where id = 1; 
Query OK, 1 row affected (0.06 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

mysql> update games set xid = 5 where id=5; 
ERROR 1644 (45000): Your custom error message 

并运行上述2更新后,命令在此表的外观

mysql> select * from games; 
+----+------+------+ 
| id | xid | val | 
+----+------+------+ 
| 1 | 4 | 1 | 
| 2 | NULL | 2 | 
| 3 | NULL | 3 | 
| 4 | 1 | 4 | 
| 5 | 2 | 5 | 
+----+------+------+ 

注意,第二更新失败,该行是不变的。

阅读更多关于此https://dev.mysql.com/doc/refman/5.5/en/signal.html

+0

作品完美!现在唯一让我感到不安的是续集不让我设置分隔符。但非常感谢! –

+1

当您在node.js上使用'sequelize'时,您只需指定触发器代码并且无需提供'delimiter'即可让库处理该问题。在CLI上运行时需要使用分隔符。 'sequelize.query(/ *触发代码* /)'或者你可以使用钩子来处理更新前的事件http://docs.sequelizejs.com/en/latest/docs/hooks/ –

+1

哦,男人,我能说什么?!而已!我不能够感谢你! –