upper函数用于将字符串转为全大写,仅影响ascii字母和部分unicode字符,中文等原样返回;常见错误包括误用其处理重音字符、在where中导致索引失效、对非字符串类型直接调用报错。

UPPER函数的基本用法和常见错误
UPPER() 是标准 SQL 中用于将字符串转为全大写的函数,几乎所有主流数据库(MySQL、PostgreSQL、SQL Server、Oracle、SQLite)都支持。但注意:它只对 ASCII 字母和部分 Unicode 字符有效,对中文、日文等无效——不是报错,而是原样返回。
常见错误是误以为 UPPER() 能处理带重音符号的字母(如 `é` → `É`),实际上多数数据库默认不支持;PostgreSQL 8.4+ 在 UTF8 编码下可正确转换,MySQL 则依赖 collation(比如 utf8mb4_unicode_ci),而 SQL Server 需要确保列使用 COLLATE Latin1_General_CI_AS 类排序规则。
- 写法统一:
SELECT UPPER('hello world');→'HELLO WORLD' - 字段调用:
SELECT UPPER(name) FROM users; - 不能直接更新:需配合
UPDATE ... SET name = UPPER(name),且目标列必须是字符串类型(VARCHAR、TEXT等)
在 WHERE 条件中使用 UPPER 进行大小写无关匹配
想查姓氏为 “smith” 的用户,不管原始数据存的是 'Smith'、'SMITH' 还是 'smith',最常用写法是:WHERE UPPER(last_name) = UPPER('smith')。
但要注意性能陷阱:对字段套函数会阻止索引使用(除非你建了函数索引)。MySQL 5.7+ 支持函数索引,PostgreSQL 和 Oracle 也支持,SQL Server 则需用计算列加索引。
- 推荐替代方案(更高效):用不区分大小写的 collation,例如 MySQL 中列定义为
last_name VARCHAR(50) COLLATE utf8mb4_0900_as_cs(注意_as_cs是大小写敏感,反而是_ci才不敏感;实际应设为utf8mb4_general_ci或utf8mb4_unicode_ci) - 临时规避索引失效:在应用层先转大写再查询,或用
LIKE配合通配符(不推荐,模糊性高) - PostgreSQL 可建表达式索引:
CREATE INDEX idx_upper_last_name ON users (UPPER(last_name));
UPPER 与 NULL、空字符串、非字符串值的交互
UPPER(NULL) 永远返回 NULL,不是空字符串也不是报错;UPPER('') 返回空字符串;若传入数字(如 UPPER(123)),多数数据库会隐式转成字符串再处理(MySQL 和 PostgreSQL 会转成 '123',SQL Server 则报错:「数据类型 int 无法转换为 varchar」)。
- 安全写法:显式转换 + COALESCE,例如
UPPER(COALESCE(CAST(age AS VARCHAR), '')) - 避免意外:检查字段类型,别对
INT或DATE直接用UPPER() - PostgreSQL 对
TEXT和CHAR行为一致;MySQL 中TINYTEXT、MEDIUMTEXT同样支持
跨数据库兼容性注意事项
语法本身几乎无差异,但底层行为受字符集和排序规则支配。同一句 UPPER('café') 在不同环境结果可能不同:MySQL 8.0 默认返回 'CAFÉ'(如果用 utf8mb4_0900_as_cs),而旧版本 MySQL 5.6 可能返回 'CAFÉ' 或 'CAFE'(丢失重音)。
- 测试关键数据:用真实含重音、连字(如
ffi)、德语 ß(应转为SS)的样本验证 - SQL Server 需确认数据库级 collation,单个字段 collation 优先级更高
- SQLite 不支持 Unicode 大小写映射(如土耳其语的 i/I 特殊规则),一律按 ASCII 处理
真正麻烦的从来不是函数怎么写,而是你没意识到当前数据库的字符集配置和 collation 实际生效路径。跑之前,先查 SHOW VARIABLES LIKE 'character_set%';(MySQL)或 SELECT pg_collation_is_visible(oid) FROM pg_collation WHERE collname = 'default';(PostgreSQL)。










