ISNUMERIC不可靠,它对'$123'、'1e4'、' '等返回1却无法转为INT;推荐SQL Server 2012+用TRY_CONVERT(INT, col) IS NOT NULL,旧版本需组合PATINDEX和显式校验。

ISNUMERIC 在 SQL Server 中不能可靠判断“字段是否为数字类型”,它只判断字符串能否被转换为任意一种数字类型(包括货币符号、科学计数法、甚至带空格的 '' +1 '),返回 1 并不意味着能安全转成 INT 或 FLOAT。
ISNUMERIC 返回 1 却无法转成 INT 的常见情况
这是最典型的误用陷阱:函数说“是数字”,但 CAST 或 CONVERT 立刻报错。
-
ISNUMERIC('$123')→ 1,但CAST('$123' AS INT)失败 -
ISNUMERIC('1e4')→ 1,但CAST('1e4' AS INT)失败(需用FLOAT) -
ISNUMERIC(' ')→ 1,CAST(' ' AS INT)失败 -
ISNUMERIC(',')→ 1(在某些排序规则下),实际根本不是数
SQL Server 2012+ 推荐用 TRY_CONVERT 替代 ISNUMERIC
它真正模拟了“尝试转换并静默失败”,返回 NULL 而非抛异常,语义清晰且可预测。
- 判断能否转为
INT:TRY_CONVERT(INT, column_name) IS NOT NULL - 判断能否转为
DECIMAL(10,2):TRY_CONVERT(DECIMAL(10,2), column_name) IS NOT NULL - 配合
CASE做条件分支:CASE WHEN TRY_CONVERT(FLOAT, col) IS NOT NULL THEN TRY_CONVERT(FLOAT, col) ELSE 0 END - 注意:空字符串
''、纯空白(如' ')对TRY_CONVERT(INT, ...)均返回 NULL,行为比ISNUMERIC更合理
需要兼容旧版本 SQL Server(2008 R2 及更早)怎么办
没有 TRY_CONVERT,只能靠组合过滤 + 显式校验,但务必避开 ISNUMERIC 单独使用:
- 先用
LEN(LTRIM(RTRIM(column_name))) > 0排除空值和纯空白 - 再用
column_name NOT LIKE '%[^0-9\-+]%'粗筛(仅适用于无小数点、无指数的整数) - 若要支持小数,需更复杂模式:
column_name NOT LIKE '%[^0-9\.\-+eE]%' AND column_name NOT LIKE '%[\.][\.]%' AND column_name NOT LIKE '%[^0-9][eE][^0-9]%'——但依然不覆盖所有边界,且性能差 - 最终仍建议在应用层做强校验,或升级数据库版本
真正难的不是写个“看起来能用”的判断,而是想清楚:你究竟需要“能转成什么类型”“允许哪些格式”“失败时怎么兜底”。ISNUMERIC 的模糊性会把这些问题掩盖起来,等数据进到计算逻辑里才暴露。










