这次上线遇到一个bug,导致回滚。定位到问题,发现是sql执行时一个语句坑了。
简单说下,就以update语句为例。
创建一个表:
CREATE TABLE `test_01` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'auto incr id', `a_id` varchar(50) NOT NULL DEFAULT ' ' COMMENT 'aid', `a_name` varchar(50) NOT NULL DEFAULT ' ' COMMENT 'aname', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8 COMMENT='test表'
插入几条数据:
insert into test_01(a_id,a_name) values('a1','n1'),('a2','n2'),('a3','n3');
ok,类型转换时的坑来了。
update test_01 set a_name='nn' where a_id=0;
更新的where条件是a_id=0,那么表里会发生更新么?
答案就是所有的行的a_name都更新为了'nn'。
为什么会发生这样的问题?因为表结构中设计的a_id是varchar类型,而更新语句中where条件的a_id是数字0。
这时就发生了类型转换的问题。mysql会把表里a_id列下所有行都转化为数字,去跟你告诉mysql的0进行比较。发现表里的a_id下转化为数字时,都转化成为了0。那么所有记录取出来就对了。
所以,在sql拼写时,一定要严格按照类型搞。
比如这个更新语句就应该写成:
update test_01 set a_name='nn' where a_id='0';// 加个引号