CAST是跨数据库通用的标准写法,语法统一为CAST(expression AS target_type),语义清晰、迁移风险低;CONVERT仅SQL Server支持且带style参数用于格式化,但不可移植。

CAST 是跨数据库通用的标准写法
如果你写的 SQL 可能跑在 SQL Server、PostgreSQL、MySQL 8.0+ 或 Oracle 上,CAST 是更稳妥的选择。它的语法统一:CAST(expression AS target_type),比如 CAST('2023-05-01' AS DATE) 在所有支持的数据库里都能执行。
它不支持格式化,也不带额外参数——这反而是优点:语义清晰、迁移风险低、ORM 生成时不易出错。但要注意,转换失败直接报错,比如 CAST('abc' AS INT) 就会中断查询。
- 适合场景:数值清洗、JOIN 条件类型对齐、INSERT 前强转
- 常见错误:
CAST('' AS INT)或CAST(' ' AS INT)在 SQL Server 中报 Conversion failed...,得先用NULLIF(col, '') - 精度问题:
CAST(3.9 AS INT)截断得 3,不是四舍五入;要四舍五入必须套ROUND()
CONVERT 是 SQL Server 特有且带 style 的格式化工具
CONVERT 只能在 SQL Server(及 Azure SQL)里用,但它多一个 style 参数,专用于控制日期/数字转字符串时的输出样式。比如 CONVERT(VARCHAR, GETDATE(), 120) 固定输出 '2023-07-20 14:30:22',不受服务器区域设置影响。
这个 style 对非日期/数字类型(如转 INT)无效,传了也忽略。而且 style 值是 SQL Server 独有的常量(如 101=mm/dd/yyyy,112=yyyymmdd),换到别的库就语法错误。
- 适用场景:报表导出固定格式日期、金额加千分位(
CONVERT(VARCHAR, 123456.78, 1)→'123,456.78') - 别踩坑:
CONVERT(DATE, '01/02/2023')在不同语言设置下可能解析成 1月2日或2月1日;安全做法是用 ISO 格式或显式指定style - 注意长度:
CONVERT(VARCHAR, col)默认长度是 30,如果源值超长会被截断,建议显式写CONVERT(VARCHAR(100), col)
WHERE 条件里用 CAST/CONVERT 容易让索引失效
把转换函数套在索引字段上,比如 WHERE CAST(order_id AS INT) > 1000,SQL Server 优化器没法走索引,只能全表扫描。这不是函数本身的问题,而是表达式破坏了索引可用性。
真正该做的,是让数据类型从源头匹配使用方式:字符串 ID 字段就别参与数值比较;非要查数值范围,优先改存储结构(比如加计算列或触发器预转换),而不是在查询里硬转。
- 临时解法:把转换移到右边,比如
WHERE order_id > '1000'(前提是字符串能按字典序正确比较) - 检查执行计划:只要看到 “Index Scan” 而不是 “Index Seek”,基本就是转换导致的
- 嵌套转换更危险,比如
CAST(REPLACE(col, '-', '') AS INT),不仅性能差,还容易因脏数据崩掉
NULL 和空字符串处理逻辑不一样
CAST(NULL AS INT) 返回 NULL 没问题,但 CAST('' AS INT) 或 CAST(' ' AS INT) 在 SQL Server 里直接报错。而 CONVERT 行为一致,同样拒绝空串。
很多人以为 ISNULL() 或 COALESCE() 能兜底,其实不行——它们只处理 NULL,不处理空字符串。真正安全的做法是组合 NULLIF():
CAST(NULLIF(TRIM(col), '') AS INT)
或者用 SQL Server 2012+ 的 TRY_CAST() / TRY_CONVERT(),失败返回 NULL 而不是报错,但注意它们不被 PostgreSQL 或 MySQL 支持。
最麻烦的其实是混合场景:一张表里 varchar 字段存了数字、空格、空串、NULL、甚至 'N/A',这时候光靠 CAST/CONVERT 不够,得先做数据探查和清洗。

















