优先用 CAST:语法为 CAST(expression AS data_type),ANSI 标准、跨库兼容;CONVERT 仅 SQL Server 支持,语法为 CONVERT(data_type, expression[, style]),style 参数专用于日期/数值格式化。

优先用 CAST,只在 SQL Server 上且需要格式控制时才用 CONVERT;两者语法、兼容性和适用场景差异明显,混用容易出错。
CAST 和 CONVERT 的语法结构怎么写对
CAST 必须用 AS 关键字,顺序固定:CAST(expression AS data_type)。漏掉 AS 或颠倒参数位置会直接报错。CONVERT 是函数式调用,目标类型在前:CONVERT(data_type, expression[, style]),style 仅对日期/数值转字符串生效,传给其他类型会被忽略。
常见错误现象:把 CONVERT(INT, '123') 写成 CONVERT('123', INT) —— 参数顺序反了,SQL Server 报错 Incorrect syntax near ','。
使用建议:
-
CAST更适合跨数据库迁移的 SQL(如从 SQL Server 迁到 PostgreSQL),改写成本低 -
CONVERT的style参数不能用于INT→VARCHAR等通用转换,只对DATETIME→VARCHAR或MONEY→VARCHAR生效 - 指定长度时都用括号,比如
CAST(name AS VARCHAR(50))、CONVERT(VARCHAR(50), name);不写长度默认为 30,可能意外截断
字符串转数字失败的典型原因和应对
最常遇到的是 Conversion failed when converting the varchar value 'abc' to data type int. 或空字符串报错。这不是函数本身的问题,而是源数据含非数字字符或空白。
关键点:
-
CAST('' AS INT)和CAST(' ' AS INT)在 SQL Server 中均报错,必须先过滤:NULLIF(TRIM(col), '')再套CAST -
CAST('12.5' AS INT)直接失败,因为INT不接受小数位;得用DECIMAL(9,2)或先ROUND() - 想“安全转换”就别硬扛,改用
TRY_CAST('12.5' AS INT)—— 失败返回NULL而非中断执行
日期字符串转换为什么总出错
核心问题是区域设置依赖:CONVERT(DATE, '01/02/2023') 在 US 设置下是 1 月 2 日,在 UK 下是 2 月 1 日;CAST('01/02/2023' AS DATE) 同样不稳定。
可靠做法只有两个:
- 统一用 ISO 格式字符串:
CAST('2023-02-01' AS DATE),不受语言/地区影响 - 显式指定
style:CONVERT(DATE, '01/02/2023', 101)(101 = mm/dd/yyyy),103 = dd/mm/yyyy,112 = yyyymmdd - 避免用
GETDATE()直接拼字符串再转,比如CAST(CONVERT(VARCHAR, GETDATE(), 101) AS DATE)—— 多此一举还多一层隐式转换风险
WHERE 条件里用 CAST/CONVERT 为什么变慢
写成 WHERE CAST(order_id AS INT) > 1000,哪怕 order_id 字段上有索引,也会强制全表扫描。优化器无法将索引 B+ 树的有序结构映射到转换后的值上。
更实际的解法:
- 如果
order_id实际是数字但存成了VARCHAR,优先改表结构:ALTER TABLE ... ALTER COLUMN order_id INT - 临时方案是把转换移到右边:
WHERE order_id > '1000'(前提是字符串能按字典序正确比较) - 实在要保留字符串存储又高频查询数值范围,考虑加计算列并建索引:
ALTER TABLE t ADD order_id_int AS TRY_CAST(order_id AS INT),再在该列建索引
真正难处理的不是单个 CAST,而是嵌套在多层 CASE、子查询或 JOIN 条件里的混合类型表达式——这时候别只盯着函数怎么写,先看执行计划里有没有 CONVERT_IMPLICIT 或 Compute Scalar 算子,那才是性能瓶颈的信号。

















