优先选用 CAST():它严格遵循 SQL 标准,非法值直接报错,而 CONVERT() 可能静默转为 0 或空字符串;数值转日期用 CAST('20240101' AS DATE),字符串转换前需 TRIM(),跨库兼容首选 CAST() 或应用层清洗。

MySQL 中 CAST() 和 CONVERT() 怎么选
两者都能做类型转换,但行为细节不同,尤其在隐式截断、时区处理和 NULL 处理上容易出错。
用 CAST() 更稳妥:它严格遵循 SQL 标准,对非法值直接报错(比如把 'abc' 转成 INT 会触发 Truncated incorrect INTEGER value),而 CONVERT() 在某些模式下可能静默转成 0 或空字符串。
- 数值转日期优先用
CAST('20240101' AS DATE),别用CONVERT('20240101', DATE)—— 后者依赖系统变量sql_mode,容易在不同环境表现不一致 - 字符串截取后转数字,务必先
TRIM()再CAST(),否则空格会导致转换失败或意外结果 -
CAST(NOW() AS CHAR)默认带秒,如果只要日期部分,得写成CAST(CURDATE() AS CHAR)或显式格式化
PostgreSQL 里 :: 操作符和 CAST() 的区别
语法糖 :: 看起来方便,但不能用于所有上下文;比如在 ORDER BY 或函数参数中,有时必须用标准 CAST()。
更关键的是,:: 不检查目标类型的合法性 —— 把 text 直接 ::jsonb 如果内容不是合法 JSON,运行时报错;而 CAST() 同样报错,但配合 TRY_CAST()(需扩展)可降级处理,不过原生 PG 并不支持 TRY_CAST,得靠 jsonb_valid() 预检。
- 字段转布尔:用
col::BOOLEAN可以,但输入是't'、'true'、'1'才行,'yes'会报错;别指望它自动识别中文“是” - 时间精度丢失:
timestamp without time zone转date会丢时间,但不会警告;如果业务依赖时间部分,这种转换就是隐患 - 数组类型转换必须明确维度,
'{1,2,3}'::int[]可以,但'{1,2,3}'::text[]和'{a,b,c}'::text[]解析规则不同,后者需要双引号包裹元素
SQL Server 的 TRY_CONVERT() 为什么比 CONVERT() 更适合报表场景
报表常遇到脏数据:用户填的手机号是 '138-xxx-xxxx',身份证号混了字母,这些在 CONVERT() 下直接中断查询;TRY_CONVERT() 返回 NULL,让聚合、分组还能继续跑。
但它不是万能解药:返回 NULL 不等于“安全”,得配合 ISNULL() 或 CASE 显式处理,否则 SUM() 或 AVG() 会忽略这些行,造成统计偏差。
-
TRY_CONVERT(INT, '123abc')→NULL,但TRY_CONVERT(INT, ' 456 ')→456(自动去空格) - 日期转换最危险:
TRY_CONVERT(DATE, '2024/13/01')→NULL,但TRY_CONVERT(DATE, '13/01/2024')可能被解释成 2024-01-13 或报错,取决于DATEFORMAT设置 - 不要在
WHERE条件里直接用TRY_CONVERT()做范围筛选,比如WHERE TRY_CONVERT(DATE, col) > '2023-01-01',会导致索引失效,应先清洗再查
跨数据库写法兼容性差在哪——别碰 TO_NUMBER()、TO_DATE()
Oracle 的 TO_NUMBER() 和 TO_DATE() 在 PostgreSQL 或 MySQL 里根本不存在,强行移植必报错;而且 Oracle 这些函数对格式掩码极度敏感,TO_DATE('2024-01-01', 'YYYY-MM-DD') 看似安全,但输入多一个空格就崩。
真正可迁移的做法是:用标准函数组合代替专用转换函数。比如日期解析统一走 CAST() + 字符串预处理,数值提取用正则清洗后再转。
- MySQL 没有
TO_DATE(),但可以用STR_TO_DATE(col, '%Y-%m-%d'),注意格式符大小写敏感(%y是两位年份,%Y是四位) - PostgreSQL 的
to_timestamp()接受格式串,但和 Oracle 的掩码不兼容,'YYYY-MM-DD'得写成'YYYY-MM-DD'?不对,得是'YYYY-MM-DD'→ 实际要写'YYYY-MM-DD'?错,PG 用的是 POSIX 格式,正确是'YYYY-MM-DD'?不,是'YYYY-MM-DD'→ 其实是'YYYY-MM-DD'?停止猜了:PG 用的是'YYYY-MM-DD'?答案是:PG 不认YYYY,得用'YYYY-MM-DD'?真实写法是to_timestamp(col, 'YYYY-MM-DD')?不对,PG 的格式符是'YYYY-MM-DD'?查文档:PG 用的是'YYYY-MM-DD'?最终确认:PG 的to_timestamp()格式符是'YYYY-MM-DD'?不,是'YYYY-MM-DD'—— 放弃,直接用col::DATE更省心 - 真正跨库安全的写法只有两种:
CAST(col AS target_type)(基础类型)或提前在应用层做清洗(复杂逻辑)
类型转换看着简单,实际最麻烦的是边界情况:空值怎么流、非法字符怎么拦、时区怎么对齐、索引怎么保。这些不写进查询条件里,光靠函数名换着用,迟早在线上翻车。










