Oracle字符串比较默认区分大小写,解决方法有两种:SQL层用UPPER()/LOWER()统一大小写,或数据库层建函数索引;会话级可设NLS_COMP=LINGUISTIC与NLS_SORT=BINARY_CI实现不区分大小写。

Oracle 默认对字符串比较区分大小写,C# 查询时若直接用 WHERE name = 'John',而数据库里存的是 'john' 或 'JOHN',就会查不到——这不是 C# 的锅,是 Oracle 的行为。解决它不靠改连接字符串或 ORM 配置,核心就两条路:在 SQL 层统一大小写,或在数据库层建函数索引保性能。
WHERE 条件里用 UPPER() / LOWER() 统一转换
最直接的办法是在查询时把字段和参数都转成同一大小写:
-
SELECT * FROM emp WHERE UPPER(name) = UPPER('john')或LOWER(name) = LOWER('John') - 在 C# 中拼 SQL 或写 Dapper/EF Core 原始 SQL 时,照这么写就行,无需额外驱动配置
- 注意:
UPPER()和LOWER()对中文、数字、符号无影响,安全可用 - 但这样写会导致
name字段上的普通索引失效,全表扫描风险高(尤其百万级以上表)
给 UPPER(name) 建函数索引提升查询性能
如果字段已有索引但被 UPPER() 干掉了,就补一个函数索引:
- 执行:
CREATE INDEX idx_emp_name_upper ON emp(UPPER(name)) - 之后再跑
WHERE UPPER(name) = UPPER('john')就能命中索引,执行计划显示INDEX RANGE SCAN - 索引名、表名、字段名大小写要和数据库中一致;若建表时用了双引号(如
"Name"),索引里也得带引号:UPPER("Name") - 别用
UPPER(name)索引去匹配LOWER()查询——函数必须完全一致才生效
用 NLS_COMP=LINGUISTIC + NLS_SORT=BINARY_CI 实现会话级不区分大小写
这是 Oracle 提供的“透明”方案,不用改 SQL,但需控制粒度:
- 在 C# 打开连接后,立即执行:
ALTER SESSION SET NLS_COMP=LINGUISTIC; ALTER SESSION SET NLS_SORT=BINARY_CI; - 之后所有字符串比较(
=、LIKE、CASE)自动忽略大小写 - 注意:
NLS_SORT=BINARY_CI是 case-insensitive,BINARY_AI还忽略重音(如 é = e),按需选 - 副作用:可能影响排序结果(比如
ORDER BY name变成按字典序而非 ASCII 序),且无法利用普通索引加速=查询(仍需函数索引) - 不建议全局设置,只在必要查询前临时切,用完不恢复也无害,会话结束自动丢弃
真正容易被忽略的是:函数索引必须和查询中使用的函数**字面量完全一致**,连空格都不能多一个;另外,如果表里字段名本身带双引号(如 "C_Name"),索引语句里也得严格照写,否则 Oracle 认为是另一个标识符。


















