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で大文字と小文字を区別しないで検索を実行するには、主に3つの方法があります。
最終的にどの方法を選択するかはあなたの個々の状況に依存します。覚えておくべき主なことは、パフォーマンスを向上させるためには大文字と小文字を区別しない検索のために正しくインデックス付けしなければならないということです。
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_1
がupper(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に注意してください。インデックスが使用されている時期と使用されていない時期を示します。
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()を使用する以外は同じ出力例を示します。
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'));
たぶんあなたは使ってみることができます
SELECT user_name
FROM user_master
WHERE upper(user_name) LIKE '%ME%'
Oracle 12c R2からは、 COLLATE operator
を使用できます。
COLLATE演算子は式の照合順序を決定します。この演算子を使用すると、標準の照合順序導出規則を使用して、データベースが式に対して導出した照合順序をオーバーライドできます。
COLLATE演算子は1つの引数collation_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"
*/
select user_name
from my_table
where nlssort(user_name, 'NLS_SORT = Latin_CI') = nlssort('%AbC%', 'NLS_SORT = Latin_CI')
あなたはそのようなことをすることができます:
where regexp_like(name, 'string$', 'i');