TRY_CAST转换失败返回NULL是设计行为,需主动处理该NULL;必须显式指定完整类型(如DECIMAL(5,2)、VARCHAR(50));不支持SQL Server 2012以下版本,且不可用于持久化计算列或CHECK约束。

TRY_CAST 转换失败不报错,但返回 NULL 是设计行为
直接用 CAST 或 CONVERT 转脏数据(比如 'N/A'、'--'、'123.45.67')会中断整个查询,抛出类似 Conversion failed when converting the varchar value 'N/A' to data type int. 的错误。而 TRY_CAST 的核心价值就是把这种“硬崩溃”变成“软处理”:转换失败时安静返回 NULL,查询继续执行。
这不是容错的终点,而是起点——你必须主动应对这个 NULL,否则后续计算(如 SUM、+ 运算)可能被污染或静默失效。
必须显式写全目标类型,漏精度/长度就报错
TRY_CAST 不接受模糊类型声明,这是和 CAST 最容易混淆的一点。它不会帮你补默认长度,写错就直接语法报错,而不是运行时报错。
-
TRY_CAST('123.45' AS DECIMAL)❌ 报错:缺少精度和小数位数 -
TRY_CAST('123.45' AS DECIMAL(5,2))✅ 正确 -
TRY_CAST('hello' AS VARCHAR)❌ 报错:VARCHAR必须带长度,如VARCHAR(50) -
TRY_CAST('123' AS INT)✅ 可以,因为INT是固定长度类型 -
TRY_CAST('2024-02-30' AS DATE)→NULL,不是报错,但你要知道非法日期也会这样“安静失败”
配合 ISNULL 处理 NULL,别依赖 ISNUMERIC 做前置判断
ISNUMERIC() 返回 1 并不等于能转成数字——比如 ISNUMERIC('1e4') 是 1,但 TRY_CAST('1e4' AS INT) 仍返回 NULL;ISNUMERIC('') 也是 1,而 TRY_CAST('' AS INT) 同样是 NULL。所以别用它当“安全开关”。
更可靠的做法是直接用 TRY_CAST 并立刻处理结果:
SELECT
input_value,
ISNULL(TRY_CAST(input_value AS DECIMAL(10,2)), 0) AS safe_amount,
CASE WHEN TRY_CAST(input_value AS INT) IS NULL THEN 'invalid' ELSE 'ok' END AS status
FROM (VALUES ('123'), ('abc'), (''), ('1e4')) t(input_value);
ISNULL 比 COALESCE 更稳妥:只接受两个参数,且强制返回第一个参数类型,避免隐式转换引发的新问题。
仅 SQL Server 2012+ 和 Azure SQL 支持,旧版本需降级方案
如果你在维护 SQL Server 2008 R2 或更早环境,TRY_CAST 会直接报错:‘TRY_CAST’ is not a recognized built-in function name. 此时只能用 TRY_CONVERT 替代(行为几乎一致),或退回到 CASE WHEN ISNUMERIC(...) = 1 AND ... THEN CAST(...) ELSE NULL END 这类手工校验逻辑。
另外注意:TRY_CAST 不能用于持久化计算列定义,也不能在 CHECK 约束中使用——这些地方要求确定性函数,而 TRY_CAST 被视为非确定性。

















