Mysql的一个双引号错位引发的血案

原来的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;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章