MySQL数据库自动强制类型转换
在使用MySQL进行SQL语句书写是,如果出现两个操作数类型不一致时,就会出现强制类型转换。这种类型转换在方便开发者的同时,也存在很大隐患。
通过以下代码看下,类型转换的表象:
select '1aaabbb'+2 ;
select 'aaabbb1'+2 ;
执行结果依次为:
3
2
可以看到已经出现了强制类型转换。主要原因就是MySQL底层的优化器发挥作用,导致隐式类型转换。
什么是隐式类型转换
在MySQL中,当操作符与不同类型的操作数一起使用时,会发生类型转换以使操作数兼容,则会发生隐式类型转换。
很明显,上面的SQL语句的执行过程中就出现了隐式转化。
其中,第一个SQL,根据字符串的第一位,转换为了数值1,出现了结果为3的情况。第二个SQL,字符串的第一位仍然是字符串,但是+
的右边是数值,导致没有转换为数值,出现了结果为2的情况。所以不能简单的使用+
号。
类型转换规则
MySQL 的类型转换遵循一定的规则,具体规则如下:
- 如果其中一个操作数是浮点数,则将其他操作数转换为浮点数。
- 如果其中一个操作数是 DECIMAL,则将其他操作数转换为 DECIMAL。
- 如果其中一个操作数是整数,则将其他操作数转换为整数。
- 如果其中一个操作数是日期或时间类型,则将其他操作数转换为日期或时间类型。
- 如果其中一个操作数是NULL,那么结果也将是NULL。
- 如果其中一个操作数是字符串,那么它将被转换为数值类型。
类型转换解决方式
不能使用简单的+
号来进行连接或操作。
MySQL提供两个函数,来达到显示的强制转换。
- CAST 函数
CAST 函数提供了一种强制类型转换的机制,它的语法如下:
CAST(value AS type)
其中,value 是需要转换的值,type 是将其转换为的类型
- CONVERT 函数
CONVERT 函数与 CAST 类似,它也可以实现数据类型转化,但其语法略有差别:
CONVERT(value, type)
其中,value 是需要转换的值,type 是将其转换为的类型
项目实际意义
在项目实际中,MySQL的类型转换,可能会带来很大的问题。
构建以下代码,用于测试:
CREATE TABLE users(
id VARCHAR(16),
name VARCHAR(128),
age INT
);
INSERT INTO users VALUES ('1', 'Alce',25), ('2', 'Bob', 30);
1、查询用户名称为0的数据。
select * from users c where c.name = 0 ;
查询结果为:
可以看到结果并未实现查询名称为0的数据,而是查询了全部的数据。
由此得出:在进行查询时,入参需要与数据库字段类型保持一致,防止查询全表的情况。所以此处应该使用string作为入参。
2、查询id+name+age的值。
select id + name + age from users;
查询结果为:
可以看到结果并不是几个数据的字符串拼接,而是类型转换后,将数据相加。
由此可以看到,在查询时,如果需要做字符串的拼接,是不可以简单的使用+
号的。此处应该使用cast等函数来进行拼接。
总结
MySQL自身存在的自动强制类型转换,在方便开发者的同时,也存在很深的隐患。项目使用时,需要了解转换的规则,避免错误的写法,多进行实际的测试,以便保证代码的正常运行。