如何在 Oracle 中进行不区分大小写的字符串比较并通过 Turkey 测试?
如何在 Oracle 中进行不区分大小写的字符串比较并通过 Turkey 测试?
默认情况下,LIKE
和其他比较运算符(=
等)的行为是区分大小写的。
是否可能使它们不区分大小写?
从10gR2开始,Oracle允许通过设置NLS_COMP
和NLS_SORT
会话参数来调整字符串比较行为:
SQL> SET HEADING OFF SQL> SELECT * 2 FROM NLS_SESSION_PARAMETERS 3 WHERE PARAMETER IN ('NLS_COMP', 'NLS_SORT'); NLS_SORT BINARY NLS_COMP BINARY SQL> SQL> SELECT CASE WHEN 'abc'='ABC' THEN 1 ELSE 0 END AS GOT_MATCH 2 FROM DUAL; 0 SQL> SQL> ALTER SESSION SET NLS_COMP=LINGUISTIC; Session altered. SQL> ALTER SESSION SET NLS_SORT=BINARY_CI; Session altered. SQL> SQL> SELECT * 2 FROM NLS_SESSION_PARAMETERS 3 WHERE PARAMETER IN ('NLS_COMP', 'NLS_SORT'); NLS_SORT BINARY_CI NLS_COMP LINGUISTIC SQL> SQL> SELECT CASE WHEN 'abc'='ABC' THEN 1 ELSE 0 END AS GOT_MATCH 2 FROM DUAL; 1
您还可以创建不区分大小写的索引:
create index nlsci1_gen_person on MY_PERSON (NLSSORT (PERSON_LAST_NAME, 'NLS_SORT=BINARY_CI') ) ;
此信息来自Oracle不区分大小写搜索。该文章提到了REGEXP_LIKE
,但它似乎也可以使用=
。
在早于10gR2版本时,实际上不能做到,如果您不需要不区分重音的搜索,常规方法是将列和搜索表达式都UPPER()
。
Oracle有三种主要方法可以执行不使用全文索引的不区分大小写搜索。
最终选择哪种方法取决于您的个人情况;记住要提高性能,必须正确为不区分大小写搜索进行索引。
1. 使列和字符串以相同的方式大小写。
您可以使用 UPPER()
或 LOWER()
强制将所有数据大小写相同:
select * from my_table where upper(column_1) = upper('my_string');
或
select * from my_table where lower(column_1) = lower('my_string');
如果在适当的情况下没有在 upper(column_1)
或 lower(column_1)
上为 column_1
创建索引,则可能会强制执行完整表扫描。为了避免这种情况,您可以创建一个 基于函数的索引。
create index my_index on my_table ( lower(column_1) );
如果使用 LIKE,则必须在要搜索的字符串周围连接一个 %
。
select * from my_table where lower(column_1) LIKE lower('my_string') || '%';
这里的SQL Fiddle 说明了所有这些查询的情况。请注意 Explain Plans,其中指示何时使用索引,何时不使用。
2. 使用正则表达式。
从 Oracle 10g 开始,可以使用 REGEXP_LIKE()
。您可以指定 _match_parameter_ 'i'
,以执行不区分大小写搜索。
为了将其用作等式操作符,必须指定字符串的开头和结尾,其由表示开头和结尾的符号(即脱字符号^和美元符号$)表示。
select * from my_table where regexp_like(column_1, '^my_string$', 'i');
为了执行等效于 LIKE 的操作,可以将这些符号删除。
select * from my_table where regexp_like(column_1, 'my_string', 'i');
使用这个需要小心,因为您的字符串可能包含正则表达式引擎会解释得不同的字符。
这里的SQL Fiddle 显示了相同的示例输出,只是使用了 REGEXP_LIKE()。
3. 在会话级别更改。
NLS_SORT 参数控制排序的排序顺序和各种比较操作符,包括等号和 LIKE。您可以通过更改会话来指定二进制、不区分大小写的排序。这将意味着在该会话中执行的每个查询都将执行不区分大小写的参数。
alter session set nls_sort=BINARY_CI
如果您想要指定不同的语言,或者使用 BINARY_AI 进行不区分音调的搜索,则可以在 语言排序和字符串搜索 中获得大量的其他信息。
您还需要更改NLS_COMP参数; 引用以下内容:
遵守NLS_SORT参数的确切运算符和查询子句取决于NLS_COMP参数的值。如果运算符或子句不遵守由NLS_COMP确定的NLS_SORT值,则使用的校对是BINARY。
NLS_COMP的默认值为BINARY;但LINGUISTIC指定Oracle应注意NLS_SORT的值:
WHERE子句和PL/SQL块的所有SQL操作的比较应使用NLS_SORT参数中指定的语言排序。为了提高性能,您还可以在要进行语言比较的列上定义语言索引。
因此,您需要再次更改会话
alter session set nls_comp=LINGUISTIC
正如文档中所述,您可能需要创建一个语言索引以提高性能
create index my_linguistc_index on my_table (NLSSORT(column_1, 'NLS_SORT = BINARY_CI'));