在Oracle中进行不区分大小写的搜索

时间:2011-03-22 12:18:08

标签: sql oracle case-sensitive case-insensitive sql-like

LIKE和其他比较运算符=等的默认行为区分大小写。

是否可以使它们不区分大小写?

6 个答案:

答案 0 :(得分:273)

在不使用全文索引的情况下,有三种主要方法可以在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');

如果column_1upper(column_1)上的lower(column_1)未编入索引,则可能会强制进行全表扫描。为了避免这种情况,您可以创建function-based index

create index my_index on my_table ( lower(column_1) );

如果你正在使用LIKE,那么你必须在你正在搜索的字符串周围连接一个%

select * from my_table where lower(column_1) LIKE lower('my_string') || '%';

This SQL Fiddle演示了所有这些查询中发生的情况。请注意解释计划,它指示何时使用索引以及何时使用索引。

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');

请注意这一点,因为您的字符串可能包含正则表达式引擎将以不同方式解释的字符。

This SQL Fiddle向您显示相同的示例输出,但使用REGEXP_LIKE()。

3。在会话级别更改它。

NLS_SORT参数控制排序的排序规则序列和各种比较运算符,包括=和LIKE。您可以通过更改会话来指定二进制,不区分大小写,排序。这意味着在该会话中执行的每个查询都将执行不区分大小写的参数。

alter session set nls_sort=BINARY_CI

如果您想要指定其他语言,或者使用BINARY_AI进行重音不敏感搜索,那么linguistic sorting and string searching周围会有大量其他信息。

您还需要更改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

如文档中所述,您可能需要创建linguistic index以提高性能

create index my_linguistc_index on my_table 
   (NLSSORT(column_1, 'NLS_SORT = BINARY_CI'));

答案 1 :(得分:74)

自10gR2起,Oracle允许通过设置NLS_COMPNLS_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 case insensitive searches。文章提到REGEXP_LIKE但它似乎也适用于旧的=


在10gR2之前的版本中,如果您不需要不区分重音的搜索,那么通常的方法就无法完成,而且通常的方法只是UPPER()列和搜索表达式。

答案 2 :(得分:47)

也许你可以尝试使用

SELECT user_name
FROM user_master
WHERE upper(user_name) LIKE '%ME%'

答案 3 :(得分:5)

从Oracle 12c R2,您可以使用COLLATE operator

  

COLLATE运算符确定表达式的排序规则。使用此运算符,您可以使用标准排序规则派生规则覆盖数据库为表达式派生的排序规则。

     

COLLATE运算符采用一个参数collat​​ion_name,您可以为其指定命名的排序规则或伪排序规则。如果归类名称包含空格,则必须用双引号将名称括起来。

演示:

CREATE TABLE tab1(i INT PRIMARY KEY, name VARCHAR2(100));

INSERT INTO tab1(i, name) VALUES (1, 'John');
INSERT INTO tab1(i, name) VALUES (2, 'Joe');
INSERT INTO tab1(i, name) VALUES (3, 'Billy'); 
--========================================================================--
SELECT /*csv*/ *
FROM tab1
WHERE name = 'jOHN' ;
-- no rows selected

SELECT /*csv*/ *
FROM tab1
WHERE name COLLATE BINARY_CI = 'jOHN' ;
/*
"I","NAME"
1,"John"
*/

SELECT /*csv*/ *
FROM tab1 
WHERE name LIKE 'j%';
-- no rows selected

SELECT /*csv*/ *
FROM tab1 
WHERE name COLLATE BINARY_CI LIKE 'j%';
/*
"I","NAME"
1,"John"
2,"Joe"
*/

<强> db<>fiddle demo

答案 4 :(得分:2)

select user_name
from my_table
where nlssort(user_name, 'NLS_SORT = Latin_CI') = nlssort('%AbC%', 'NLS_SORT = Latin_CI')

答案 5 :(得分:1)

你可以这样做:

where regexp_like(name, 'string$', 'i');