隐式类型转换 自动完成
- 把操作数类型转换为适合操作符计算的相应类型。
比方说对于加法操作符+来说,它要求两个操作数都必须是数字才能进行计算,所以如果某个操作数不是数字的话,会将其隐式转换为数字,比方说下边这几个例子:
1 + 2 → 3
'1' + 2 → 3
'1' + '2' → 3
虽然'1'、'2'都是字符串,但是如果它们作为加法操作符+的操作数的话,都会被强制转换为数字,所以上边几个表达式其实都会被当作1 + 2去处理的,这些表达式被放在查询列表时的效果如下:
SELECT 1 + 2, '1' + 2, '1' + '2';
将函数参数转换为该函数期望的类型。
我们拿用于拼接字符串的CONCAT函数举例,这个函数以字符串类型的值作为参数,如果我们在调用这个函数的时候,传入了别的类型的值作为参数,MySQL会自动把这些值的类型转换为字符串类型的:
CONCAT('1', '2') → '12'
CONCAT('1', 2) → '12'
CONCAT(1, 2) → '12'
虽然1、2都是数字,但是如果它们作为CONCAT函数的参数的话,都会被强制转换为字符串
SELECT CONCAT('1', '2'), CONCAT('1', 2), CONCAT(1, 2);
- 存储数据时,把某个值转换为某个列需要的类型。
我们先新建一个简单的表t:
CREATE TABLE t (
i1 TINYINT,
i2 TINYINT,
s VARCHAR(100)
);
这个表有三个列,列i1和i2是用来存储整数的,列s是用来存储字符串的,如果我们在存储数据的时候填入的不是期望的类型,就像这样:
INSERT INTO t(i1, i2, s) VALUES('100', '100', 200);
我们为列i1和i2填入的值是一个字符串值:'100',列s填入的值是一个整数值:200,虽然说类型都不对,但是由于隐式类型转换的存在,在插入数据的时候字符串'100'会被转型为整数100,整数200会被转型成字符串'200',所以最后插入成功,我们来看一下效果:
SELECT * FROM t;
类型转换的注意事项
尽量转换
MySQL会尽量把值转换为表达式中需要的类型,而不是产生错误。
按理说'23sfd'这个字符串无法转换为数字,但是MySQL规定只要字符串的开头部分包含数字,那么就把这个字符串转换为开头的数字,如果开头并没有包含数字,那么将被转换成0,比方说这样:
'23sfd' → 23
'2019-08-28' → 2019
'11:30:32' → 11
'sfd' → 0
SELECT '23sfd' + 0, 'sfd' + 0;
这种强制转换不能用于存储数据中 insert
INSERT INTO t(i1, i2, s) VALUES('sfd', 'sfd', 'aaa');
ERROR 1366 (HY000): Incorrect integer value: 'sfd' for column 'i1' at row 1
由于i1和i2列需要整数,而填入的字符串'sfd'并不能顺利的转为整数,所以报错了。
在运算时会自动提升操作数的类型 超过范围
我们知道不同数据类型能表示的数值范围是不一样的,在小的数据类型经过算数计算后得出的结果可能大于该可以表示的范围。比方说t表中有一条记录如下:
SELECT * FROM t;
其中的i1列和i2列的类型都是TINYINT,而TINYINT能表示的最大正整数是127,如果我们把i1列的值和i2列的值相加会发生什么呢?请看:
SELECT i1 + i2 FROM t;
可以看到最后的结果是200,可是它已经超过TINYINT类型的表示范围了。
MySQL自动将整数类型的操作数提升到了BIGINT,这样就不会产生运算结果太大超过TINYINT能表示的数值范围的尴尬情况了。类似的,有浮点数的运算过程会把操作数自动转型为DOUBLE类型。
自动化转换防止错误