<p>MySQL中不能直接用BINARY判断全大写,需结合正则:SELECT * FROM users WHERE name REGEXP '^A-Z0-9[:punct:]+$' AND name NOT REGEXP '[a-z]';</p>

如何用BINARY关键字检测字段是否全为大写
MySQL中,BINARY 强制按字节比较,能绕过默认的大小写不敏感排序规则。但要注意:BINARY 作用于整个字符串比较,不能直接判断“是否全大写”,得配合函数一起用。
常见错误是写成 WHERE BINARY name = UPPER(name) —— 这在多数情况下看似可行,但一旦字段含非字母字符(如空格、数字、标点),或使用了 utf8mb4_unicode_ci 等排序规则,UPPER() 可能不改变原值,导致误判。
正确做法是:先确保只比对字母字符,再逐字符验证。更稳妥的实操路径是用正则:
SELECT * FROM users WHERE name REGEXP '^[A-Z[:punct:][:space:][:digit:]]+$' AND name NOT REGEXP '[a-z]';
说明:
- 第一个
REGEXP限定只含大写字母、数字、标点、空白(避免出现小写字母以外的非法字符) - 第二个
NOT REGEXP '[a-z]'是关键,排除任何小写字母 - 注意:MySQL 8.0+ 才支持
[:punct:]等 POSIX 类;5.7 及以前建议用^[A-Z0-9[:punct:][:space:]]+$并额外加name = UPPER(name)辅助过滤
SQL Server里用COLLATE指定大小写敏感排序规则
SQL Server 默认排序规则(如 SQL_Latin1_General_CP1_CI_AS)是大小写不敏感(CI),所以 WHERE name = UPPER(name) 永远为真——根本不起作用。
必须显式切换为大小写敏感(CS)规则,例如:
SELECT * FROM users WHERE name COLLATE Latin1_General_CS_AS = UPPER(name) COLLATE Latin1_General_CS_AS;
要点:
-
COLLATE必须同时加在左右两边,否则隐式转换会把右边又转回 CI 规则 - 推荐用
Latin1_General_CS_AS(区分大小写 + 区分重音),避免用_BIN类规则(二进制比较可能因 Unicode 归一化导致意外不等) - 如果字段是
varchar,注意排序规则是否兼容;nvarchar字段推荐用Latin1_General_100_CS_AS_SC_UTF8(SQL Server 2019+)
PostgreSQL中区分大小写的本质是操作符而非排序规则
PostgreSQL 没有 BINARY,也不靠 COLLATE 控制大小写敏感性——它的 = 操作符本身就是大小写敏感的。所以最简方式就是:
SELECT * FROM users WHERE name = UPPER(name);
但陷阱在于:如果字段含 Unicode 字符(比如德语 ß、土耳其语 İ),UPPER() 行为依赖系统 locale 和 LC_CTYPE 设置,可能和预期不符。
更可靠的做法是用正则 + Unicode 属性:
SELECT * FROM users WHERE name ~ '^[A-Z0-9[:punct:][:space:]]+$' AND name !~ '[a-z]';
说明:
-
~是大小写敏感正则匹配,!~是取反 - PostgreSQL 的
[a-z]默认匹配所有小写 Unicode 字母(取决于数据库 locale),比UPPER()更稳定 - 若需严格 ASCII 大写(即只认 A–Z),改用
WHERE name ~ '^[A-Z0-9[:punct:][:space:]]+$' AND name !~ '[^A-Z0-9[:punct:][:space:]]'并去掉小写检查
跨数据库统一方案:应用层预处理比SQL硬判断更可控
纯 SQL 判断“全大写”本质上是在做文本分类,而不同数据库对 Unicode、空格、不可见字符(如零宽空格 \u200b)、组合字符(如 é = e + ´)的处理差异极大。
实际项目中,容易被忽略的点包括:
- 字段开头/结尾有不可见空白(
TRIM()必须加,且要确认是否含\r、\n、\t甚至\u00A0) - 中文、日文等字符没有“大小写”概念,但
UPPER()可能返回原值,导致误判为“全大写” - MySQL 5.7 对多字节字符的
UPPER()支持有限,遇到 emoji 或生僻汉字会静默失败
如果业务逻辑允许,更推荐在应用层用确定性更强的逻辑处理:
- Python:用
str.isupper()(它自动跳过非字母字符,只检查至少有一个字母且全为大写) - Java:用
StringUtils.isAllUpperCase()(Apache Commons Lang),或手动遍历Character.isLetter(c) && !Character.isUpperCase(c)
SQL 层只做粗筛(比如 WHERE name NOT LIKE '%[a-z]%'),精细判断交给应用——尤其当字段内容不可控时。

















