O comportamento padrão de LIKE
e de outros operadores de comparação, =
etc faz distinção entre maiúsculas e minúsculas.
É possível torná-los sem distinção entre maiúsculas e minúsculas?
REGEXP_LIKE(username,'me','i')
LIKE?
O comportamento padrão de LIKE
e de outros operadores de comparação, =
etc faz distinção entre maiúsculas e minúsculas.
É possível torná-los sem distinção entre maiúsculas e minúsculas?
REGEXP_LIKE(username,'me','i')
LIKE?
Respostas:
Desde 10gR2, o Oracle permite ajustar o comportamento das comparações de cadeias, definindo os parâmetros NLS_COMP
e NLS_SORT
session:
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
Você também pode criar índices que não diferenciam maiúsculas de minúsculas:
create index
nlsci1_gen_person
on
MY_PERSON
(NLSSORT
(PERSON_LAST_NAME, 'NLS_SORT=BINARY_CI')
)
;
Essas informações foram obtidas de pesquisas que não diferenciam maiúsculas de minúsculas do Oracle . O artigo menciona, REGEXP_LIKE
mas parece funcionar bem =
também.
Nas versões anteriores a 10gR2, isso realmente não pode ser feito, e a abordagem usual, se você não precisar de pesquisa sem distinção de sotaque , é apenas UPPER()
a coluna e a expressão de pesquisa.
LIKE
Expressões arbitrárias (por exemplo WHERE foo LIKE '%abc%'
) já são lentas o suficiente se não puderem ser indexadas, não acho que esteja especificamente relacionado à sensibilidade a casos.
DBD::Oracle
, você pode escrever $ENV{NLS_SORT} = 'BINARY_CI'; $ENV{NLS_COMP} = 'LINGUISTIC';
antes de chamar `DBI-> connect`.
ALTER SESSION
único altera sua instância local da correção e isso significa como sua sessão atual, ou seja, se eu fechar e reabrir, ela será redefinida. Existe uma maneira que eu possa ver o que os valores atuais são de modo que se a sua persistiu em todos os lugares que eu posso mudar de volta para as configurações originais ...
Existem três maneiras principais de executar uma pesquisa que não diferencia maiúsculas de minúsculas no Oracle sem usar índices de texto completo.
Em última análise, o método escolhido depende das circunstâncias individuais; o principal a lembrar é que, para melhorar o desempenho, você deve indexar corretamente a pesquisa que não diferencia maiúsculas de minúsculas.
Você pode forçar todos os seus dados a serem o mesmo caso usando UPPER()
ou LOWER()
:
select * from my_table where upper(column_1) = upper('my_string');
ou
select * from my_table where lower(column_1) = lower('my_string');
Se column_1
não estiver indexado upper(column_1)
ou lower(column_1)
, conforme apropriado, isso poderá forçar uma verificação completa da tabela. Para evitar isso, você pode criar um índice baseado em funções .
create index my_index on my_table ( lower(column_1) );
Se você estiver usando o LIKE, precisará concatenar uma %
sequência de caracteres que está procurando.
select * from my_table where lower(column_1) LIKE lower('my_string') || '%';
Este SQL Fiddle demonstra o que acontece em todas essas consultas. Observe os planos de explicação, que indicam quando um índice está sendo usado e quando não está.
A partir do Oracle 10g, REGEXP_LIKE()
está disponível. Você pode especificar o _match_parameter_ 'i'
, para executar uma pesquisa que não diferencia maiúsculas de minúsculas.
Para usar isso como um operador de igualdade, você deve especificar o início e o fim da sequência, que é indicada pelo quilate e pelo sinal de dólar.
select * from my_table where regexp_like(column_1, '^my_string$', 'i');
Para executar o equivalente a LIKE, eles podem ser removidos.
select * from my_table where regexp_like(column_1, 'my_string', 'i');
Tenha cuidado com isso, pois sua sequência pode conter caracteres que serão interpretados de maneira diferente pelo mecanismo de expressão regular.
Este SQL Fiddle mostra o mesmo exemplo de saída, exceto usando REGEXP_LIKE ().
O parâmetro NLS_SORT controla a sequência de intercalação para pedidos e os vários operadores de comparação, incluindo =
e LIKE. Você pode especificar uma classificação binária, sem distinção entre maiúsculas e minúsculas, alterando a sessão. Isso significa que todas as consultas executadas nessa sessão executam parâmetros que não diferenciam maiúsculas de minúsculas.
alter session set nls_sort=BINARY_CI
Há muitas informações adicionais sobre classificação linguística e pesquisa de strings, se você deseja especificar um idioma diferente ou fazer uma pesquisa sem distinção de sotaque usando BINARY_AI.
Você também precisará alterar o parâmetro NLS_COMP ; citar:
Os operadores exatos e as cláusulas de consulta que obedecem ao parâmetro NLS_SORT dependem do valor do parâmetro NLS_COMP. Se um operador ou cláusula não obedecer ao valor NLS_SORT, conforme determinado por NLS_COMP, o agrupamento usado é BINARY.
O valor padrão de NLS_COMP é BINARY; mas, LINGUISTIC especifica que o Oracle deve prestar atenção ao valor de NLS_SORT:
As comparações para todas as operações SQL na cláusula WHERE e nos blocos PL / SQL devem usar a classificação linguística especificada no parâmetro NLS_SORT. Para melhorar o desempenho, você também pode definir um índice linguístico na coluna para o qual deseja comparações linguísticas.
Então, mais uma vez, você precisa alterar a sessão
alter session set nls_comp=LINGUISTIC
Conforme observado na documentação, você pode criar um índice linguístico para melhorar o desempenho
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') || '%';
vez de select * from my_table where lower(column_1) LIKE lower('my_string%');
? Isso dá alguma vantagem?
regexp_like
, existe uma maneira de escapar dessas seqüências? Dando um exemplo, se a string tiver $, a saída não será a esperada. // cc @Ben e outros, por favor, compartilhem.
`
é o caractere de escape @bozzmob. Não deve haver diferença na saída se a string na qual a expressão regular está operando contiver a $
, isso só poderá causar problemas se você precisar de um $
literal em sua expressão regular. Se você tiver um problema específico, eu faria outra pergunta se este comentário / resposta não ajudar.
talvez você possa tentar usar
SELECT user_name
FROM user_master
WHERE upper(user_name) LIKE '%ME%'
WHERE upper(user_name) LIKE UPPER('%ME%')
isso? :)
UPPER
o parâmetro de entrada também?
upper
função de perder o índice, você tem alguma idéia de como fazer pesquisas usando o índice?
No Oracle 12c R2, você poderia usar COLLATE operator
:
O operador COLLATE determina o agrupamento de uma expressão. Esse operador permite substituir o agrupamento que o banco de dados derivaria para a expressão usando regras de derivação de agrupamento padrão.
O operador COLLATE usa um argumento, collation_name, para o qual você pode especificar um agrupamento nomeado ou pseudo-agrupamento. Se o nome do agrupamento contiver um espaço, coloque-o entre aspas duplas.
Demo:
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')
%
's no primeiro argumento para a sua segunda NLSSORT
são não pretende ser wildcards, certo? Eles meio que confundem.