原来的sql语句如下:
update `credit_bill` set receipt_no = 'DD-20181022-89757' where receipt_no = 'DD-20181022-316736';
该sql正常执行。
变化后的sql语句如下:
update `credit_bill` set receipt_no = 'DD-20181022-89757 where receipt_no' = 'DD-20181022-316736';
此时引号错位了,执行结果也变了。执行结果变成,把表中所有的记录的receipt_no字段的值都更新成了0。
很神奇,但究竟是如何产生这样的结果的呢,mysql内部又是如何转义的呢?
转义后的sql语句变成了这样:
update `credit_bill` set receipt_no = ('DD-20181022-89757 where receipt_no' = 'DD-20181022-316736');
注:如果把括号提前,变成这样:
update `credit_bill` set (receipt_no = 'DD-20181022-89757 where receipt_no') = 'DD-20181022-316736';
是会报错的,语法错误。
执行上面的sql,先执行括号内的语句,其实等同于:
select 'DD-20181022-89757 where receipt_no' = 'DD-20181022-316736';
其查询结果为0,所以整条sql语句就等同于:
update `credit_bill` set receipt_no = 0
谜底揭开。
补充:
以上情况类似的select语句如下:
select * from credit_bill where receipt_no = 'xxx' = 'yyy';
等同于:
select * from credit_bill where (receipt_no = 'xxx') = 'yyy';
执行时,括号内的语句查询出来等于0或1。然后比较其结果和字符串'yyy'。
等号一边是int,一边是字符串,两边会都转成float进行比较。
'yyy'转成浮点型值为0。如果左边也是0,那么就等同于0和0比较,而0恒等于0。
所以原sql等同于select * from credit_bill where 1=1;