MySQL中判断纯数字字段应使用col REGEXP '^[0-9]+$',要求至少一位数字且整字段匹配;需额外加col IS NOT NULL排除NULL值,空字符串和全角数字不匹配。

用 REGEXP 或 RLIKE 判断纯数字字段(MySQL)
MySQL 8.0+ 支持 REGEXP,想筛出「只含数字」的字符串,不能只写 ^[0-9]*$——它会把空字符串也放进来。更稳妥的是 ^[0-9]+$,要求至少一位数字。
常见错误是漏掉锚点:WHERE col REGEXP '[0-9]+' 会匹配 "abc123def",因为子串 "123" 符合;必须加 ^ 和 $ 锁定整字段。
示例:
SELECT * FROM users WHERE phone REGEXP '^[0-9]+$';
注意:如果字段可能为 NULL,REGEXP 默认返回 NULL,需额外排除:WHERE phone IS NOT NULL AND phone REGEXP '^[0-9]+$'。
ISNUMERIC() 在 SQL Server 中不可靠
SQL Server 的 ISNUMERIC() 会把 '.'、'+'、'1e4'、甚至 ',' 都判为数字,实际转 INT 时直接报错。它只表示「能被某种数字类型接受」,不是「纯十进制整数」。
真正安全的做法是结合 TRY_CAST()(SQL Server 2012+):
-
TRY_CAST(col AS BIGINT) IS NOT NULL→ 确保可转成整数且无溢出 - 若允许前导零或固定长度(如 11 位手机号),还得加长度检查:
LEN(col) = 11 AND TRY_CAST(col AS BIGINT) IS NOT NULL - 注意:空格会被
TRY_CAST自动 trim,但制表符、换行符不会,建议先TRIM(col)
PostgreSQL 用 ~ 和 ^\d+$ 更简洁
PostgreSQL 原生支持 POSIX 正则,~ 操作符比写 REGEXP 更轻量。模式用 ^\d+$ 即可(\d 等价于 [0-9],且不匹配 Unicode 数字,符合多数场景预期)。
容易踩的坑:
-
^\d*$会包含空字符串,生产环境应避免 - 字段含前后空格?得先
TRIM(col)再匹配,否则' 123 '不通过 - 性能敏感时,正则比函数索引慢;若过滤高频,考虑加生成列 + 索引:
ALTER TABLE t ADD COLUMN is_digits BOOLEAN GENERATED ALWAYS AS (col ~ '^[0-9]+$') STORED
通用兜底方案:用 TRANSLATE() 清除非数字再比长度(兼容老版本)
某些旧数据库(如 Oracle 10g、早期 SQL Server)不支持正则,可用字符替换思路:把所有数字替换成空,再看结果是否为空字符串。
以 PostgreSQL/Oracle 为例:
WHERE TRANSLATE(col, '0123456789', '') = ''
SQL Server 需用嵌套 REPLACE()(难看但有效):
WHERE REPLACE(REPLACE(REPLACE(col, '0', ''), '1', ''), '2', '') = '' -- 依此类推到 '9'
缺点明显:
- 可读性差,维护成本高
- 无法处理空值和空字符串边界(
TRANSLATE(NULL, ...)返回NULL) - 一旦字段含 Unicode 数字(如阿拉伯数字),这个方法就失效
所以只建议作为临时兼容手段,优先升级或改用正则支持的版本。
真正麻烦的从来不是写对一行正则,而是确认业务定义的「数字」到底指什么:是否允许负号?小数点?科学计数法?前导零?这些语义差异,往往比语法更早决定你该用哪个函数。

















