跨数据库环境必须用CAST,90%报错源于脏值而非语法错误;CAST严格遵循CAST(expression AS data_type),CONVERT为CONVERT(data_type, expression[, style]);字符串转数字前须清洗空格、字母等脏数据;日期转换唯一安全格式是ISO标准'YYYY-MM-DD';WHERE中对字段用CAST/CONVERT会导致索引失效。

跨数据库环境必须用 CAST,硬套函数不清洗数据,90% 的报错都来自脏值而非语法。
CAST 和 CONVERT 语法写错的典型表现
漏掉 AS、参数顺序颠倒、长度括号位置不对,都会直接报错。比如 CAST('123' INT) 缺 AS,SQL Server 报错 Incorrect syntax near 'INT';CONVERT('123', INT) 把表达式放前面,报 Incorrect syntax near ','。
-
CAST严格按CAST(expression AS data_type),AS不可省,目标类型在后 -
CONVERT是函数调用风格:CONVERT(data_type, expression[, style]),目标类型在前 - 指定长度时括号必须跟在类型名后:
CAST(name AS VARCHAR(50)),不是CAST(name AS VARCHAR)(50) -
style参数只对DATETIME→VARCHAR或MONEY→VARCHAR生效,传给INT→VARCHAR会被忽略
字符串转数字失败,不是函数问题而是数据问题
Conversion failed when converting the varchar value 'N/A' to data type int 这类报错,99% 情况下不是 CAST 或 CONVERT 写错了,而是字段里混着空格、单位、字母、空串甚至不可见字符。
-
CAST('' AS INT)和CAST(' ' AS INT)在 SQL Server 中均报错,得先NULLIF(TRIM(col), '') - MySQL 不支持
TRY_CAST,得靠正则兜底:CAST(IF(col REGEXP '^[0-9]+$', col, NULL) AS SIGNED) - PostgreSQL 要用
NULLIF(REGEXP_REPLACE(col, '[^0-9.-]', '', 'g'), '')清洗后再转 -
CAST('12.5' AS INT)必然失败,INT 不接受小数位;想截断得用CAST('12.5' AS DECIMAL(9,0))或显式ROUND()
日期字符串转换最危险,ISO 格式是唯一共识
CAST('06/22/2026' AS DATE) 在 SQL Server(MDY)和 PostgreSQL(默认 DMY 或依赖 datestyle)中结果可能完全相反。别指望它跨库一致。
- 唯一安全写法:
CAST('2026-06-22' AS DATE)—— 所有主流数据库都认 ISO 格式 - SQL Server 里若必须处理非 ISO 字符串,用
CONVERT(DATE, '22/06/2026', 103)显式指定 style(103 = dd/mm/yyyy) -
CONVERT(VARCHAR, GETDATE(), 120)输出2026-06-22 14:30:22,但复制到 pgAdmin 就报错:function convert(unknown, unknown) does not exist - 避免嵌套转换,如
CAST(CONVERT(VARCHAR, GETDATE(), 101) AS DATE)—— 多一层隐式转换,多一个出错点
WHERE 条件里用 CAST/CONVERT 导致索引失效
写成 WHERE CAST(order_id AS INT) > 1000,哪怕 order_id 字段上有索引,也会触发全表扫描。
- 根本原因是表达式作用于列上,优化器无法使用索引进行范围查找
- 更优解是改数据:把字符串字段清洗后存为正确类型,或加计算列并建索引(SQL Server 支持
PERSISTED) - 临时方案可用覆盖索引 + 过滤条件前置,但不如源头治理可靠
- MySQL 中类似写法还可能触发隐式转换,进一步放大性能偏差
真正难的从来不是函数怎么写,而是你是否知道那条报错记录里藏着一个没 trim 的空格、一个被当成日期的“—”符号、或者一个在 SQL Server 里能跑通但在迁移当天让整张报表崩掉的 CONVERT(..., 105)。

















