ISNUMERIC返回1仅表示字符串可能转为某种数值类型(如money、float),不代表能安全转为INT或DECIMAL;例如'1e4'、'$'、','均返回1但CAST会失败,推荐SQL Server 2012+使用TRY_CAST替代。

ISNUMERIC函数返回1不代表字符串能转成数字
ISNUMERIC 是 SQL Server 特有的函数,它只判断字符串“是否可能被解释为某种数字类型”,而不是“是否能安全转为 INT 或 FLOAT”。比如 ISNUMERIC('1e4')、ISNUMERIC('$')、ISNUMERIC(',')' 都返回 1——但这些显然不能直接 CAST 成整数。
真正想判断“能否转为整数”得自己写逻辑
SQL Server 没有内置的 ISINTEGER,常见做法是组合 TRY_CAST(2012+)或正则风格的 LIKE 检查:
- 用
TRY_CAST('123' AS INT):成功返回值,失败返回NULL,再用IS NOT NULL判断即可 - 若必须兼容旧版本(如 2008),可用
NOT LIKE '%[^0-9]%' AND LEN(TRIM(col)) > 0粗筛纯数字字符串(注意:不支持负号、不处理开头空格) - 要支持负数和小数?
TRY_CAST仍是首选,它天然支持'-42'、'3.14'、'1e2'等格式
ISNUMERIC在WHERE子句中直接转换会报错
下面写法很危险:
SELECT * FROM t WHERE ISNUMERIC(col) = 1 AND CAST(col AS INT) > 100
因为 SQL Server 的短路求值不保证顺序,即使 ISNUMERIC 返回 0,CAST 仍可能提前执行并炸掉。正确写法是:
- 用
TRY_CAST(col AS INT)替代CAST,整个表达式不会报错 - 或者把过滤拆成子查询/CTE,先筛出可转数值的行,再做计算
- 避免在同一个
WHERE条件里混用判断函数和强制转换
其他数据库没有ISNUMERIC,别硬搬
PostgreSQL、MySQL、SQLite 都不支持 ISNUMERIC:
- PostgreSQL 推荐
col ~ '^[+-]?\d+\.?\d*$'(简单正则)或自定义函数 +TO_NUMBER()异常捕获 - MySQL 8.0+ 可用
col REGEXP '^[+-]?[0-9]+\.?[0-9]*$',但注意它不识别科学计数法 - SQLite 没原生数字判断,常用
col = CAST(col AS NUMERIC)—— 依赖其弱类型隐式转换特性,但结果不可靠(如'1abc'也会转成 1)
跨数据库迁移时,最稳的方式还是应用层做校验,数据库只存明确类型字段。

















