mysql查询字段未加引号问题及隐式转换

1. 问题重现

最近线上出了个问题,用户明明没有投票,却提示已投票,我查询数据,刚开始没有查出数据,后来却查出数据了,以为没有问题,后来以为是插入的时候通过int类型插入,导致varchar类型的索引没有添加这条索引(天真的想法),再后来看到查出来的数据和我查询的数据并不一致,最后一位不太相同,知道应该是发生了mysql隐式转化问题。

接下来就来研究下不加引号或者加引号的情况。

2. 问题探讨

先看看数据结构:
在这里插入图片描述

  • id为数字型
  • name为字符串类型

测试数据:
在这里插入图片描述

2.1 varchar字段查询:

  1. 可以看出通过123456789123456788也能查出123456789123456789的数据。
    mysql查询字段未加引号问题及隐式转换_第1张图片2. 可以看出123456789123456777也查出结果了。mysql查询字段未加引号问题及隐式转换_第2张图片3. 可以看出123456789123456666并没有查出结果,这里我们可以分析出,数字转为字符串的时候,有效位是16位。
    mysql查询字段未加引号问题及隐式转换_第3张图片
  2. 可以看出12345678912345678也没有查出结果,说明长度不一致也不能查出结果,所以我觉得数字转字符串如果超出16位,后面是用占位符代替的,类似like中的占位符。mysql查询字段未加引号问题及隐式转换_第4张图片

2.2 int类型字段查询

  1. 可以看出通过’1aaa’也能查出数字类型的1
    mysql查询字段未加引号问题及隐式转换_第5张图片
  2. 但是’11’是不可以的。
    mysql查询字段未加引号问题及隐式转换_第6张图片

3. mysql隐式转化:

隐式类型转换规则:

  1. 如果一个或两个参数均为NULL,则比较的结果为NULL,除了 相等比较运算符。对于NULL NULL,结果为true。
  2. 如果比较操作中的两个参数都是字符串,则将它们作为字符串进行比较。
  3. 如果两个参数都是整数,则将它们作为整数进行比较。
  4. 如果不与数字比较,则将十六进制值视为二进制字符串。
  5. 如果参数之一是 timestamp 或 datatime column,而另一个参数是常量,则在执行比较之前,该常量将转换为时间戳。
  6. 如果参数之一是十进制值,则比较取决于另一个参数。如果另一个参数是十进制或整数值,则将参数作为十进制值进行比较;如果另一个参数是浮点值,则将参数作为浮点值进行比较。
  7. 在所有其他情况下,将参数作为浮点数(实数)进行比较。例如,将字符串和数字操作数进行比较,将其作为浮点数的比较。

3.1 测试:

mysql查询字段未加引号问题及隐式转换_第7张图片
mysql查询字段未加引号问题及隐式转换_第8张图片
从结果可以看出,在字符串和int比较时,字符串会被隐式转换为0值

你可能感兴趣的:(mysql,mysql,数据库,java)