MySQL中判断合法数字最稳妥方式是正则匹配,推荐使用^[+-]?[0-9]*\.?[0-9]+([eE][+-]?[0-9]+)?$,覆盖带符号十进制数及科学计数法,且必须加^和$锚定。

MySQL 中用 REGEXP 判断字符串是否为合法数字
MySQL 没有内置的 IS_NUMBER() 函数,直接用 CAST() 或 CONVERT() 容易静默截断或转成 0,不可靠。最稳妥的方式是正则匹配——但要注意「合法数字」的定义:是否允许负号、小数点、科学计数法、开头空格?
常见需求是判断「带符号的十进制数(含小数)」,推荐这个正则:
^[+-]?[0-9]*\.?[0-9]+([eE][+-]?[0-9]+)?$
它能覆盖:"123"、"-45.67"、"+.8"、"1.23e-4",但拒绝 "12."、"abc"、"12a3"、" "。
-
^[+-]?:可选正负号,必须在开头 -
[0-9]*\.?[0-9]+:整数部分可省(如.5),但必须有小数位;避免.单独出现 -
([eE][+-]?[0-9]+)?:科学计数法可选,指数必须为整数 - 务必加
^和$,否则'abc123def'也会被误判为真
PostgreSQL 中用 ~ 或 pg_typeof() 辅助判断
PostgreSQL 支持更严格的类型转换检查。单纯用正则(~ 操作符)和 MySQL 类似,但更推荐结合异常捕获逻辑——不过 SQL 层无法直接 try/catch,所以常用折中方案:
对字段 val 做安全转换判断:
SELECT val,
CASE
WHEN val ~ '^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$'
THEN CAST(val AS NUMERIC)
ELSE NULL
END AS safe_num
FROM your_table;
注意两点:
一款AI工具,主要用于手动 Telegram 斜杠命令,用于查看 Codex 状态及使用情况。用户发送 /codex_usage、/codex_usage default、/codex_usage all 等时触发,适合需要提升相关任务效率的用户。
- PostgreSQL 的
NUMERIC转换比 MySQL 更严格,'123 '(尾部空格)会报错,所以正则里不能漏掉^\s*和\s*$——但建议先用TRIM(val)预处理 - 如果只要布尔结果,直接用
val ~ '...' AND val !~ '.*[^0-9+-.eE].*'反向排除非法字符更省事(适用于简单场景)
SQL Server 中慎用 ISNUMERIC()
ISNUMERIC() 是个经典陷阱函数:它对 '$'、'.'、','、甚至 '1e4' 都返回 1,但这些值实际无法转成 INT 或 FLOAT。它只表示「可能能被某种数字类型接受」,不是「合法数字字符串」。
真正可用的方式是尝试转换并捕获失败:
- SQL Server 2012+ 推荐用
TRY_CAST(val AS FLOAT)—— 成功返回数值,失败返回NULL - 若只要真假判断:
TRY_CAST(val AS FLOAT) IS NOT NULL - 注意:
TRY_CAST('123.45.67' AS FLOAT)返回NULL,而ISNUMERIC('123.45.67')返回 1 —— 差异极大 - 空字符串
''、纯空格会被TRY_CAST当作NULL,符合直觉;ISNUMERIC('')却返回 0
通用建议:别只靠 SQL 做格式校验
SQL 层做数字合法性判断,本质是把应用层该干的活挪到数据库。性能差、可读性低、正则难维护。更合理的方式是:
- 在应用代码中用语言原生解析(如 Python 的
float()+try/except,Go 的strconv.ParseFloat()) - 入库前清洗:把明显非法值(空、全空格、含字母)直接过滤或标为
NULL - 数据库字段类型设为
NUMERIC或FLOAT,靠 DDL 约束兜底,而非运行时查 - 如果必须 SQL 判断,优先选带
TRY_*前缀的函数(SQL Server、Azure SQL),其次正则(MySQL/PG),最后才考虑ISNUMERIC()这类历史包袱函数
正则写错一个字符,比如漏了 ^ 或多了一个 *,结果就完全不可信——这种细节,在 review 时最容易被忽略。










