在学习廖雪峰的Java 教程时,其中有一条SQL 语句很奇怪:
SELECT id, name, gender FROM students WHEREgender='F'AND grade=3
这句语句运行出来是这样的结果:
| id | name | gender |
|---|---|---|
| 11 | 小林 | 0 |
| 12 | 小王 | 0 |
然而数据表的定义却是这样的:
| FieldName | FieldType | NULL | Default |
|---|---|---|---|
| Id | bigint(20) | No | 0 |
| name | varchar(50) | No | |
| gender | tinyint(1) | No | 0 |
| grade | int(11) | No | 0 |
可以看到gender 是TinyInt 类型的,但在查询时传入字符进去却没有报错(先不管结果对不对),这就很奇怪。
一番捣鼓之后,发现实际上是MySQL 会对这种参数进行字符分割。当字段定义的为数值类型时,其就会把传入的参数分割,只留下数值,字符或字符串丢掉。例如:... WHERE gender='123#F' ...就会被分开为123和#F,只保留123,别的就扔了。当参数只有字符或字符串时,就全丢掉,然后将这个参数的值替换为默认值0,最后再做查询。
至于为啥会往数值字段传字符,主要是因为程序当中需要用占位符的方式构建SQL 语句,其中的占位符的值不能为空,就随便填了个字符进去。