web-dev-qa-db-ja.com

Oracleでの大文字と小文字を区別しない検索

LIKEおよびその他の比較演算子=などのデフォルトの動作では、大文字と小文字が区別されます。

大文字と小文字を区別しないようにすることは可能ですか。

204
sergionni

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()を使用します。列と検索式の両方。

74

フルテキストインデックスを使用せずに、Oracleで大文字と小文字を区別しないで検索を実行するには、主に3つの方法があります。

最終的にどの方法を選択するかはあなたの個々の状況に依存します。覚えておくべき主なことは、パフォーマンスを向上させるためには大文字と小文字を区別しない検索のために正しくインデックス付けしなければならないということです。

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)でインデックス付けされていない場合は、必要に応じて全表スキャンを強制することができます。これを避けるために 関数ベースのインデックス を作成することができます。

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 これら全てのクエリで何が起こるのかを示しています。 Explain Planに注意してください。インデックスが使用されている時期と使用されていない時期を示します。

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を使用してアクセントを区別しない検索をしたい場合は、 言語ソートと文字列検索 に関する追加情報がたくさんあります。

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

たぶんあなたは使ってみることができます

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

Oracle 12c R2からは、 COLLATE operator を使用できます。

COLLATE演算子は式の照合順序を決定します。この演算子を使用すると、標準の照合順序導出規則を使用して、データベースが式に対して導出した照合順序をオーバーライドできます。

COLLATE演算子は1つの引数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 <>フィドルデモ

6
Lukasz Szozda
select user_name
from my_table
where nlssort(user_name, 'NLS_SORT = Latin_CI') = nlssort('%AbC%', 'NLS_SORT = Latin_CI')
2
Clodoaldo Neto

あなたはそのようなことをすることができます:

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