优先选cast:跨数据库兼容且符合ansi标准;convert仅sql server支持,含style参数但不可移植,换库即失效。

CAST 和 CONVERT 选哪个?先看数据库环境
跨库迁移或 ORM 自动生成 SQL → 必用 CAST;纯 SQL Server 且需输出 '2026-06-22 14:30' 这类格式化字符串时,才考虑 CONVERT。MySQL 中 CONVERT(expr, type) 虽能用,但参数顺序和行为与 SQL Server 不一致;PostgreSQL 直接报错 function convert(unknown, unknown) does not exist。
常见错误:把 CONVERT(INT, '123') 写成 CONVERT('123', INT) —— 参数颠倒,SQL Server 报 Incorrect syntax near ','。
-
CAST语法固定:CAST(expression AS data_type),漏掉AS就报错 -
CONVERT是函数式调用:CONVERT(data_type, expression[, style]),style只对DATETIME→VARCHAR或MONEY→VARCHAR生效,传给INT→VARCHAR会被忽略 - 指定长度必须带括号:
CAST(name AS VARCHAR(50)),不写默认 30,可能意外截断
字符串转数字失败?90% 是脏数据惹的祸
Conversion failed when converting the varchar value 'N/A' to data type int 这类报错,几乎从不来自函数写法,而是源字段混着空格、单位、字母、空串。硬套 CAST 或 CONVERT 不清洗数据,等于主动触发中断。
- SQL Server 推荐组合:
TRY_CAST(TRIM(col) AS INT)——TRIM去首尾空格,TRY_CAST容错返回NULL - MySQL 没
TRY_CAST,得前置过滤:CAST(IF(col REGEXP '^[0-9]+$', col, NULL) AS SIGNED) - PostgreSQL 得用正则:
CAST(NULLIF(REGEXP_REPLACE(col, '[^0-9.-]', '', 'g'), '') AS NUMERIC) -
CAST('' AS INT)在 SQL Server 中直接报错;CAST('123.45.67' AS DECIMAL(5,2))在 MySQL 中静默截断为123.45,不是报错
日期字符串转换最危险,ISO 格式是唯一共识
CAST('22/06/2026' AS DATE) 在 SQL Server(MDY)、PostgreSQL(依赖 datestyle)、MySQL(可能返回 NULL)中结果完全不同。别指望它跨环境一致。
- 安全做法只有两条:
CAST('2026-06-22' AS DATE)(所有数据库都认 ISO 格式),或 SQL Server 专用:CONVERT(DATE, '22/06/2026', 103)(103 = dd/mm/yyyy) -
CONVERT(DATE, '01/02/2023', 101)明确表示 mm/dd/yyyy,112表示 yyyymmdd,避免区域歧义 - 别用
CAST(CONVERT(VARCHAR, GETDATE(), 101) AS DATE)—— 多一层隐式转换,还增加出错点
WHERE 条件里用 CAST/CONVERT 为什么变慢?
在 WHERE 子句中对列使用 CAST(col AS INT) 或 CONVERT(INT, col),会导致该列无法走索引,执行计划变成全表扫描。这不是函数本身慢,而是破坏了索引可用性。
- 根本解法:建表时就用正确类型,避免运行时转换
- 若必须转换,优先在值侧操作:
WHERE col = CAST('123' AS VARCHAR(10)),而不是WHERE CAST(col AS VARCHAR(10)) = '123' - SQL Server 中,
TRY_CAST和TRY_CONVERT虽可防错,但不解决性能问题——它们照样阻断索引
真正麻烦的从来不是函数怎么写,而是你没看清数据长什么样、目标库认不认、执行路径有没有被悄悄绕开。










