CAST和CONVERT均为SQL Server中类型转换函数:CAST符合ANSI标准、跨库兼容,语法为CAST(expression AS data_type);CONVERT是SQL Server扩展,支持style参数精准控制日期等格式化输出,如CONVERT(VARCHAR, GETDATE(), 120)。

CAST 和 CONVERT 都能强制转换类型,但不是随便换就能跑通——字段里混着空格、字母、非法日期时,CAST 会直接报错或静默变 NULL,CONVERT 在 SQL Server 里多一个容错入口,但跨库就失效。
CAST(expression AS target_type) 怎么写才不崩
标准写法看着简单,实际踩坑最多:CAST(col AS INT) 在 MySQL 里遇到 '123abc' 可能截成 123,在 PostgreSQL 里直接报错,在 SQL Server 里也可能中断整个查询。
- 必须先清理:对字符串列,先
TRIM(col)去首尾空格,再用正则过滤(如col REGEXP '^[0-9]+$'或col ~ '^\d+$') - 避免精度陷阱:比如
CAST('123.456789' AS DECIMAL(5,2))在 SQL Server 中会报错(超出小数位),MySQL 可能四舍五入但不保证,PostgreSQL 直接拒绝 - 日期类最危险:直接
CAST('2023/13/01' AS DATE)全库基本都炸;应先用TRY_PARSE(SQL Server)、TO_DATE(PostgreSQL)或正则提取合法部分再转
CONVERT 在 SQL Server 里比 CAST 多什么
CONVERT 是 SQL Server 特有函数,核心优势不在“能不能转”,而在“怎么格式化输出”。它第三个参数 style 是关键,CAST 完全没有这个能力。
- 日期转字符串必须靠它:比如
CONVERT(VARCHAR, GETDATE(), 120)输出'2026-04-18 01:57:00',而CAST(GETDATE() AS VARCHAR)结果依赖服务器设置,不可控 - 字符串转日期也更稳:用
CONVERT(DATE, '04/18/2026', 101)明确告诉引擎这是MM/DD/YYYY格式,比裸CAST少猜 - 但它不能解决源头脏数据:如果传进来的字符串是
'abc',CONVERT(INT, 'abc')同样报错,不比CAST更宽容
跨数据库迁移时 CAST 和 CONVERT 哪个更安全
答案很干脆:CAST 更可移植,但“能跑”不等于“结果一致”。不同数据库对同一句 CAST('1.23' AS DECIMAL(5,2)) 的处理逻辑可能完全不同。
- MySQL:允许前导空格,容忍部分非法字符(静默截断),默认用
DECIMAL表示定点数 - PostgreSQL:严格校验,
' 1.23 '会失败,必须TRIM;且只认NUMERIC,DECIMAL是别名但精度行为略有差异 - SQL Server:溢出时可能截断或报错,取决于
ARITHABORT设置;CONVERT的style参数在其他库根本不存在 - SQLite:压根不支持
DECIMAL,只认NUMERIC,且不校验精度,CAST('1.23456789' AS NUMERIC(3,2))不报错但存的是原始浮点值
遇到转换失败该不该用 TRY_CAST 或 TRY_PARSE
SQL Server 2012+ 提供 TRY_CAST 和 TRY_PARSE,它们失败时返回 NULL 而非中断查询——但这只是“兜底”,不是“免检”。
-
TRY_CAST(col AS INT)对'123abc'返回NULL,但你得确认NULL在业务逻辑里是否可接受(比如聚合时被忽略、JOIN 时丢失记录) -
TRY_PARSE(REPLACE(price_col, '$', '') AS DECIMAL(10,2))比裸CAST安全,但替换逻辑要覆盖所有单位变体('USD'、'€'、' per kg') - PostgreSQL 16+ 才有
TRY_CAST,旧版只能靠case when col ~ '^\d+(\.\d+)?$' then col::numeric else null end手动模拟 - MySQL 至今没原生
TRY_CAST,得用IF+CONVERT组合判断,性能差一截
真正麻烦的从来不是语法怎么写,而是你永远不知道那条看似干净的字符串字段里,藏着第几行数据正等着在生产环境凌晨三点触发转换失败。










