try_cast转换失败时返回null而非报错,因其是sql server 2012+专设的安全转换函数,将硬性断言降级为可空表达式,避免查询中断;常见失败场景包括字母、空字符串、小数转int、非法日期及科学计数法等,且不支持隐式截断或精度溢出。

TRY_CAST转换失败时为什么不会报错
因为TRY_CAST是SQL Server 2012+专门设计的“安全转换”函数,它把类型转换从硬性断言(CAST)降级为可空表达式:只要源值无法合法映射到目标类型,就返回NULL,而不是抛出Msg 241这类中断查询的错误。这和CAST或CONVERT有本质区别——后者在第一行失败时整个结果集就没了,而TRY_CAST让查询继续跑完所有行。
哪些值传给TRY_CAST会返回NULL
不是所有“看起来像”的字符串都能转成功。常见返回NULL的情况包括:
-
TRY_CAST('abc' AS INT)→NULL(纯字母) -
TRY_CAST('' AS INT)→NULL(空字符串) -
TRY_CAST('123.45' AS INT)→NULL(小数不能隐式截断) -
TRY_CAST('2024-02-30' AS DATE)→NULL(非法日期) -
TRY_CAST('1e4' AS INT)→NULL(科学计数法不被INT接受)
注意:TRY_CAST(' 42 ' AS INT)能成功(自动trim空格),但TRY_CAST(CHAR(9) + '42' AS INT)会失败(制表符不被trim)。
WHERE里用TRY_CAST容易踩的性能坑
别直接写WHERE TRY_CAST(value_str AS INT) > 100——这个表达式无法利用value_str列上的索引,必然触发全表扫描。尤其当表有百万行时,响应会明显变慢。
更实际的做法:
- 临时查数:先用
WHERE value_str LIKE '[0-9]%'快速过滤掉明显非数字的行,再套TRY_CAST - 高频查询:加计算列
ALTER TABLE t ADD safe_int AS TRY_CAST(value_str AS INT) PERSISTED,然后对safe_int建索引 - 别依赖
ISNUMERIC()前置判断:ISNUMERIC('1e4')返回1,但TRY_CAST('1e4' AS INT)仍是NULL,二者语义不等价
TRY_CAST和TRY_CONVERT怎么选
优先用TRY_CAST,除非你明确需要格式控制:
-
TRY_CAST('01-02-2024' AS DATE)行为依赖当前会话的DATEFORMAT,生产环境不可控 -
TRY_CONVERT(DATE, '01-02-2024', 103)强制按dd/mm/yyyy解析,样式码错就返NULL,不静默错配 -
TRY_CAST('123' AS DECIMAL(5,2))和TRY_CONVERT(DECIMAL(5,2), '123')结果一致,但前者更标准、性能略优
真正要警惕的是精度溢出这种“静默失败”:比如TRY_CAST('123.456' AS DECIMAL(5,2))返回NULL,但没人报错提醒你——得靠业务逻辑主动检查结果是否为NULL。










