跨数据库环境必须用CAST,SQL Server单独部署且需格式控制时才考虑CONVERT;90%报错源于脏数据未清洗。CAST语法为CAST(expression AS data_type),漏AS或颠倒顺序即报错;CONVERT为CONVERT(data_type, expression[, style]),参数顺序错误同样报错;字符串转数字前须TRIM+NULLIF,日期转换应优先用ISO格式'YYYY-MM-DD'。

直接说结论:跨数据库环境必须用 CAST,SQL Server 单独部署且需要控制日期/数字格式时才考虑 CONVERT;硬套函数不清洗数据,90% 的报错都来自脏值,不是语法写错了。
CAST 和 CONVERT 语法写错的典型表现
最常见的错误是参数顺序和关键字混淆:
-
CAST必须带AS,顺序固定为CAST(expression AS data_type);漏掉AS或写成CAST(data_type AS expression)会直接报错 -
CONVERT是函数式调用,目标类型在前:CONVERT(data_type, expression[, style]);把CONVERT(INT, '123')写成CONVERT('123', INT),SQL Server 报Incorrect syntax near ',' - 指定长度时括号不能省:
CAST(name AS VARCHAR(50))正确,CAST(name AS VARCHAR)默认按 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('12.5' AS INT)必然失败,INT 不接受小数位;应改用DECIMAL(9,2)或先ROUND() - 想“安全转换”就别硬扛:
TRY_CAST('12.5' AS INT)失败返回NULL,不中断执行;MySQL 没TRY_CAST,得靠IF(col REGEXP '^[0-9]+$', col, NULL)预过滤
日期字符串转换最危险,ISO 格式是唯一共识
区域设置会让 CAST('01/02/2023' AS DATE) 在 US 环境解析为 1 月 2 日,在 UK 解析为 2 月 1 日——结果不可控:
- 唯一可靠做法是统一用 ISO 格式:
CAST('2023-02-01' AS DATE),所有主流数据库都认 - SQL Server 中若必须处理非 ISO 输入,显式指定
style:CONVERT(DATE, '01/02/2023', 101)(101 = mm/dd/yyyy),103= dd/mm/yyyy,120= yyyy-mm-dd hh:mi:ss(ODBC 规范,推荐) - 避免嵌套转换,比如
CAST(CONVERT(VARCHAR, GETDATE(), 101) AS DATE)—— 多一层隐式转换,还引入区域依赖风险
WHERE 条件里用 CAST/CONVERT 为什么变慢
写成 WHERE CAST(order_id AS INT) > 1000,哪怕 order_id 字段上有索引,也会强制全表扫描:
- 因为转换发生在列上,优化器无法利用索引;正确做法是转换传入值:
WHERE order_id > CAST('1000' AS INT)(前提是字段本身是数值型) - 如果字段本身就是
VARCHAR存数字,又必须走范围查询,优先考虑建计算列索引或提前清洗入库,而不是每次查都CAST -
CONVERT(VARCHAR, datetime_col, 120)这类操作放在SELECT列表里影响不大,但放在WHERE或JOIN条件里就是性能杀手
真正难的从来不是怎么写对函数,而是判断该不该转、在哪转、谁来转——数据源头没规范,再熟练的 CAST 也兜不住。










