convert仅适用于sql server,跨数据库应使用cast;日期转换需指定style参数(如103对应dd/mm/yyyy);字符串转数字前须清理空值和脏数据;where中使用convert会导致索引失效,应优先修改字段类型或添加持久化计算列。

CONVERT只在SQL Server里有效
别在MySQL或PostgreSQL里写CONVERT——它们要么报错function convert(unknown, unknown) does not exist,要么参数顺序相反(MySQL是CONVERT(expr, type),SQL Server是CONVERT(type, expr[, style])),一复制就崩。跨库脚本必须用CAST,比如CAST(col AS DATE)在所有主流数据库都认。
日期字符串转换失败:没加style参数是主因
写CONVERT(DATE, '25/03/2024')大概率报错Msg 241, Level 16, State 1,因为SQL Server默认按US格式解析,把25当月看。解决方法只有显式指定style:
-
CONVERT(DATE, '25/03/2024', 103)→ dd/mm/yyyy(英国) -
CONVERT(DATE, '03/25/2024', 101)→ mm/dd/yyyy(美国) -
CONVERT(DATE, '2024-03-25', 120)→ yyyy-mm-dd(ODBC标准,最稳)
注意:style只对DATETIME、VARCHAR等少数类型生效,转INT时传了也忽略。
字符串转数字:空值和脏数据得先处理
CONVERT(INT, '')或CONVERT(INT, ' ')直接报错,不是返回NULL。常见坑点:
- 先用
NULLIF(TRIM(col), '')干掉空串和空格 - 再用
TRY_CONVERT(INT, ...)替代CONVERT——失败返回NULL,不炸 - 如果源字段含单位(如'45.6 kg'),得先
REPLACE或正则清理,否则TRY_CONVERT也救不了
WHERE里用CONVERT会让索引失效
写WHERE CONVERT(INT, order_no) > 1000,哪怕order_no上有索引,也会全表扫描。真正该做的:
- 优先改数据:把
order_no字段类型直接改成INT(如果业务允许) - 次选生成列:
ALTER TABLE orders ADD order_no_int AS TRY_CONVERT(INT, order_no) PERSISTED,然后给这个计算列建索引 - 实在不行,把转换移到右边:
WHERE order_no > '1000'(前提是字符串能字典序比较)
CONVERT的灵活性容易让人忽略底层代价——它不是万能胶,而是临时拐杖;真要高频查询,类型不一致本身就是设计缺陷。










