原文链接
Implicit type conversion
一些规则:
- 两个参数至少有一个是 NULL 时,比较的结果也是 NULL,例外是使用 <=> 对两个 NULL 做比较时会返回 1,这两种情况都不需要做类型转换
- 两个参数都是字符串,会按照字符串来比较,不做类型转换
- 两个参数都是整数,按照整数来比较,不做类型转换
- 十六进制的值和非数字做比较时,会被当做二进制串
- 有一个参数是
TIMESTAMP 或 DATETIME,并且另外一个参数是常量,常量会被转换为 timestamp
- 有一个参数是 decimal 类型,如果另外一个参数是 decimal 或者整数,会将整数转换为 decimal 后进行比较,如果另外一个参数是浮点数,则会把 decimal 转换为浮点数进行比较
- 所有其他情况下,两个参数都会被转换为浮点数再进行比较
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| mysql> select '55aaa' = 55; +--------------+ | '55aaa' = 55 | +--------------+ | 1 | +--------------+ 1 row in set, 1 warning (0.00 sec)
mysql> select 'a' + '55'; +------------+ | 'a' + '55' | +------------+ | 55 | +------------+ 1 row in set, 1 warning (0.00 sec)
|
可以登录系统
1
| SELECT * FROM users WHERE username = 'a' OR 1='1' AND password = 'anyvalue'
|
主要是针对字符串部分
隐式转化把字符串转为了double类型。但是因为字符串是非数字型的,所以就会被转换为0,因此最终计算的是0+1=1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| mysql> select 'a'+'b'='c'; +-------------+ | 'a'+'b'='c' | +-------------+ | 1 | +-------------+ 1 row in set, 3 warnings (0.00 sec)
mysql> show warnings; +---------+------+---------------------------------------+ | Level | Code | Message | +---------+------+---------------------------------------+ | Warning | 1292 | Truncated incorrect DOUBLE value: 'a' | | Warning | 1292 | Truncated incorrect DOUBLE value: 'b' | | Warning | 1292 | Truncated incorrect DOUBLE value: 'c' | +---------+------+---------------------------------------+ 3 rows in set (0.00 sec)
|
这样当进行select,update或者delete的时候就可能会多操作一些数据。所以应该加引号的地方别忘记了。
当把字符串转为数字的时候,其实是从左边开始处理的。
- 如果字符串的第一个字符就是非数字的字符,那么转换为数字就是0
- 如果字符串以数字开头
- 如果字符串中都是数字,那么转换为数字就是整个字符串对应的数字
- 如果字符串中存在非数字,那么转换为的数字就是开头的那些数字对应的值