推荐使用 cast 而非 convert 进行显式类型转换,因 cast 符合 sql 标准、行为稳定;合法目标类型包括 signed、unsigned、decimal(m,d)、char(n)、date、datetime、time 等,禁用 int/float 等非标准名。

直接用 CAST,别碰 CONVERT 做类型转换——它语法歧义大、旧版本行为不稳,而 CAST 是 SQL 标准写法,MySQL 各版本表现一致。
CAST 的合法目标类型有哪些
MySQL 不接受 INT、FLOAT、STRING 这类“口语化”类型名,只认官方白名单。写错会报 Truncated incorrect INTEGER value 或直接失败。
-
SIGNED或UNSIGNED:对应有/无符号整数,不是INT -
DECIMAL(M,D):必须带精度,如DECIMAL(10,2),不能只写DECIMAL -
CHAR或CHAR(N):转字符串,N可选,超长会被截断 -
DATE/DATETIME/TIME:输入必须是标准格式(如'2023-05-01'),非标准格式(如'05/01/2023')静默返回NULL
字符串转数值时的静默陷阱
MySQL 对非法输入不报错,而是返回默认值,极易掩盖数据质量问题。
-
CAST('abc123' AS SIGNED)→0,不是报错 -
CAST('' AS SIGNED)→0,空字符串也变 0 -
CAST('123.45.67' AS DECIMAL(5,2))→123.45,遇到第二个点就停,不校验完整性
真要转,先用正则或 REGEXP 过滤:WHERE col REGEXP '^[0-9]+(\.[0-9]+)?$',再套 CAST。
WHERE 和 ORDER BY 里用 CAST 的性能代价
在条件或排序中对字段加 CAST,基本等于主动放弃索引。
-
WHERE CAST(phone AS CHAR) LIKE '138%':即使phone是BIGINT且有索引,执行计划中key为NULL -
ORDER BY CAST(created_at AS DATE):不如直接用DATE(created_at),后者更易被优化器识别
长期方案是建生成列:ALTER TABLE users ADD phone_str VARCHAR(20) STORED AS (CAST(phone AS CHAR)),再对 phone_str 加索引。
CONVERT 留给字符集转换,别用它转类型
CONVERT 有两个重载签名:CONVERT(expr, type) 和 CONVERT(expr USING charset)。解析器靠上下文判断,容易误判。
-
CONVERT('123', SIGNED)在某些 MySQL 5.7 实例中会被当作字符集转换失败 - 想转字符集?必须用
CONVERT(col USING utf8mb4),CAST不支持USING - 纯类型转换场景下,
CONVERT没有额外优势,反而多一层不可控
真正容易被忽略的是:空值和边界值处理逻辑不统一——CAST('' AS DATE) 得 NULL,但 CAST('' AS SIGNED) 得 0,这种差异在聚合或比较时可能引发隐性 bug。











