mysql不提供isnumeric()函数,替代方案仅正则匹配和类型转换兜底;推荐用^-?[0-9]+(.[0-9]+)?$校验整数、负数、小数,需注意空字符串、前导零、数值溢出等语义问题。

MySQL 中没有 ISNUMERIC() 函数
很多刚从 SQL Server 或 PostgreSQL 转过来的人会直接写 ISNUMERIC('123'),结果报错:Unknown function 'ISNUMERIC'。MySQL 从 8.0 到最新版(截至 2026 年)都**不提供 ISNUMERIC() 内置函数**。别试了,它不存在。
替代方案只有三种:正则匹配、类型转换试探、或用 CAST()/CONVERT() 配合错误处理逻辑(但 MySQL 不支持 TRY_CAST)。所以实际能稳定用的,就只剩 REGEXP 和类型转换兜底这两种路。
用 ^[0-9]+$ 匹配纯整数(不含负号、小数点、空格)
这是最常见也最容易踩坑的写法。比如判断字段 str_col 是否只含数字:
SELECT str_col, str_col REGEXP '^[0-9]+$' AS is_digit FROM t;
注意这组边界符 ^ 和 $ 缺一不可——否则 'abc123def' 也会返回 1(因为中间有连续数字)。
-
'123'→ 1(正确) -
'12.3'→ 0(小数点不被接受) -
'-5'→ 0(负号不被接受) -
' 123 '→ 0(前后空格导致开头/结尾不匹配) -
'123a'→ 0(含字母,正确拒绝)
如果业务允许前导/尾随空格,得先套一层 TRIM(str_col);如果要支持负数,得改成 '^-?[0-9]+$';如果还要支持小数,就得更复杂——见下一条。
支持整数、负数、小数的正则:^-?[0-9]+.?[0-9]*$
这个模式看起来合理,但有陷阱:它会把 '123.'(末尾带点)、'.'、'-.' 都判为合法。真正安全的浮点数校验需要排除这些边界情况。
推荐用这个更严谨的写法:
str_col REGEXP '^-?[0-9]+(\.[0-9]+)?$'
说明:
-
^-?:可选负号 -
[0-9]+:至少一位数字(强制整数部分存在) -
(\.[0-9]+)?:小数部分是「点 + 至少一位数字」的整体,且整体可选
这样 '123.45'、'-7'、'0.0' 都过,而 '123.'、'.'、'abc' 全部失败。
注意:MySQL 中反斜杠要写成双反斜杠 \.,否则会被当作文本点(即任意字符)解析。
为什么不用 [^0-9.] 这种“找非数字”思路?
有人看到 '123a' REGEXP '[^0-9.]' 返回 1 就以为“有非数字就不是数字”,然后反向用 NOT 包一层,写成:
NOT (str_col REGEXP '[^0-9.]')
这看似简洁,但问题很大:
- 空字符串
''会通过(因为没匹配到任何非数字字符) -
'.'也会通过(它里面没有「非数字且非点」的字符) -
'..'、'-.'同样漏判 - 没处理空格、制表符、Unicode 空格等隐形字符
本质是这种写法在做「排除法」,但排除条件太弱,无法保证「全是有效数字字符」。正向定义模式(如 ^-?[0-9]+(\.[0-9]+)?$)才可控。
真正容易被忽略的点是:正则只管字符形状,不管语义合法性。比如 '0123' 是合法整数,但若业务要求「不能有前导零」,就得额外加逻辑;再比如超长数字(如 50 位)可能能过正则,但转成 DECIMAL 时溢出——正则不负责数值范围校验。











