优先用CAST,因其跨数据库兼容性更好;CONVERT仅SQL Server/Sybase支持且含样式参数,但不可移植。

CAST 和 CONVERT 用哪个?先看数据库类型
MySQL、PostgreSQL、SQLite 只支持 CAST;SQL Server 和 Sybase 同时支持 CAST 和 CONVERT,但 CONVERT 多一个格式化参数(比如日期转字符串时控制样式)。如果你写的是跨数据库 SQL,优先用 CAST,它更标准、更可移植。
常见错误现象:CONVERT(VARCHAR, GETDATE(), 120) 在 PostgreSQL 里直接报错 function convert(unknown, unknown, integer) does not exist。
-
CAST语法统一:CAST(expr AS target_type) -
CONVERT有两种写法:SQL Server 中CONVERT(target_type, expr)或带样式的CONVERT(target_type, expr, style) - PostgreSQL 的
::语法(如'2023-01-01'::DATE)是CAST的简写,不是通用标准,别在别处硬套
隐式转换出问题了,为什么显式 CAST 还报错?
不是所有字符串都能转成数字或日期——CAST 遇到非法值会直接报错(比如把 'abc' 转 INT),而某些数据库的隐式转换可能静默失败或截断。关键点在于:错误发生在运行时,且不因字段有 NULL 就跳过。
使用场景:清洗脏数据时,比如日志表里的 user_age 是 VARCHAR,但含 'N/A'、空格、甚至 '25 years'。
- SQL Server 可用
TRY_CAST('abc' AS INT)返回 NULL 而不报错;但 MySQL 和 PostgreSQL 没原生TRY_*函数 - PostgreSQL 可用
NULLIF(trim(age_str), '')::INT RESCUE NULL不行——它不支持 RESCUE;得靠CASE WHEN age_str ~ '^\d+$' THEN age_str::INT END - MySQL 8.0+ 可用
CAST(SAFE_CAST(age_str AS SIGNED))?不行,MySQL 根本没有SAFE_CAST;得用CAST(IF(age_str REGEXP '^[0-9]+$', age_str, NULL) AS SIGNED)
日期转字符串:CONVERT 的 style 参数真香,但别乱用
SQL Server 的 CONVERT(VARCHAR, GETDATE(), 120) 输出 '2023-01-01 12:34:56',看着干净。但这个 120 是 SQL Server 特有编码,换到其他数据库就失效。更麻烦的是,style 值对区域设置敏感——比如 103(dd/mm/yyyy)在英国有效,在美国服务器上可能被忽略或报错。
性能影响:带 style 的 CONVERT 比纯 CAST 多一次格式解析,高并发导出报表时能测出毫秒级差异。
- 跨库兼容写法:用
CAST转成DATE或TIMESTAMP,再靠应用层格式化 - 如果必须数据库内格式化,SQL Server 推荐用
FORMAT(GETDATE(), 'yyyy-MM-dd HH:mm:ss')(但性能更差,且 2012+ 才支持) -
CONVERT(VARCHAR, date_col, 0)看似“默认格式”,其实输出带冗余空格和 AM/PM,不适合拼接或 API 输出
小数精度丢失?别只盯 CAST,先看源字段精度
把 DECIMAL(10,2) 的 99.995 用 CAST(... AS DECIMAL(10,2)) 转,结果是 100.00——不是函数 bug,是四舍五入规则生效了。但更隐蔽的问题是:源字段如果是 FLOAT 或 REAL,二进制存储本身就有精度误差,CAST 只是把它暴露出来。
使用场景:财务计算、统计报表中要求精确小数位。
- 永远别对
FLOAT字段做等值判断后再 CAST,比如WHERE CAST(price AS DECIMAL(10,2)) = 19.99—— 先 CAST 源字段,再比较 - MySQL 中
CAST(1.1 + 2.2 AS DECIMAL(10,2))结果是3.30,但底层1.1 + 2.2实际是3.3000000000000003,CAST 会四舍五入 - PostgreSQL 的
NUMERIC类型在 CAST 时默认截断而非四舍五入,行为和 SQL Server 不同,测试时得实测
CAST 转 JSON,8.0 才行;SQL Server 2016+ 的 TRY_CAST 在老环境直接语法报错。动手前,先 SELECT @@VERSION 或查文档。

















