답변:
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()
은 열과 검색 표현식 모두입니다.
LIKE
표현 (예 :) WHERE foo LIKE '%abc%'
은 색인을 생성 할 수 없다면 이미 충분히 느립니다. 특히 대소 문자 구분과 관련이 있다고 생각하지 않습니다.
DBD::Oracle
작성할 수 있습니다 $ENV{NLS_SORT} = 'BINARY_CI'; $ENV{NLS_COMP} = 'LINGUISTIC';
.
ALTER SESSION
수정의 로컬 인스턴스 만 변경하고 현재 세션과 같은 의미입니다. 즉, 닫았다가 다시 열면 재설정되었을 것입니다. 현재의 값이 무엇인지 알 수있는 방법이 있습니까? 어디에서나 지속되는 경우 원래 설정으로 다시 변경할 수 있습니다.
전체 텍스트 인덱스를 사용하지 않고 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') || '%';
이 SQL Fiddle 은 이러한 모든 쿼리에서 발생하는 상황을 보여줍니다. 설명 계획은 인덱스가 사용되는시기와 사용되지 않는시기를 나타냅니다.
Oracle 10g부터 REGEXP_LIKE()
사용할 수 있습니다. 'i'
대소 문자를 구분하지 않는 검색을 수행하기 위해 _match_parameter_를 지정할 수 있습니다 .
이것을 항등 연산자로 사용하려면 문자열의 시작과 끝을 지정해야하며 캐럿과 달러 기호로 표시됩니다.
select * from my_table where regexp_like(column_1, '^my_string$', 'i');
LIKE와 동등한 기능을 수행하기 위해 LIKE를 제거 할 수 있습니다.
select * from my_table where regexp_like(column_1, 'my_string', 'i');
문자열에 정규식 엔진에서 다르게 해석되는 문자가 포함될 수 있으므로주의하십시오.
이 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 * from my_table where lower(column_1) LIKE lower('my_string') || '%';
대신 왜 다른지 물어봐도 select * from my_table where lower(column_1) LIKE lower('my_string%');
될까요? 이점이 있습니까?
regexp_like
가있는 경우 그러한 문자열을 벗어날 수있는 방법이 있습니까? 예를 들어 문자열에 $가 있으면 출력이 예상과 다릅니다. // cc @Ben과 다른 사람들은 공유하십시오.
어쩌면 당신은 사용해 볼 수 있습니다
SELECT user_name
FROM user_master
WHERE upper(user_name) LIKE '%ME%'
WHERE upper(user_name) LIKE UPPER('%ME%')
그때 생각해 봤어 ? :)
UPPER
입력 매개 변수 를 사용하지 않는 이유는 무엇입니까?
upper
는 인덱스를 잃는 기능을 사용합니다. 인덱스를 사용하여 검색하는 방법을 알고 있습니까?
Oracle 12c R2에서 다음을 사용할 수 있습니다 COLLATE operator
.
COLLATE 연산자는 표현식의 데이터 정렬을 결정합니다. 이 연산자를 사용하면 표준 데이터 정렬 파생 규칙을 사용하여 데이터베이스가 식에 대해 파생 한 데이터 정렬을 재정의 할 수 있습니다.
COLLATE 연산자는 이름이 지정된 콜 레이션 또는 의사 콜 레이션을 지정할 수있는 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')
%
두 번째 주장에서 ' NLSSORT
은 (는) 와일드 카드 가 아닙니다 . 그들은 혼란스러워합니다.