El comportamiento predeterminado de LIKE
y los otros operadores de comparación, =
etc. distingue entre mayúsculas y minúsculas.
¿Es posible hacerlos insensibles a mayúsculas y minúsculas?
REGEXP_LIKE(username,'me','i')
lugar de LIKE?
El comportamiento predeterminado de LIKE
y los otros operadores de comparación, =
etc. distingue entre mayúsculas y minúsculas.
¿Es posible hacerlos insensibles a mayúsculas y minúsculas?
REGEXP_LIKE(username,'me','i')
lugar de LIKE?
Respuestas:
Desde 10gR2, Oracle permite ajustar el comportamiento de las comparaciones de cadenas configurando los parámetros de sesión NLS_COMP
y 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
También puede crear índices sin distinción entre mayúsculas y minúsculas:
create index
nlsci1_gen_person
on
MY_PERSON
(NLSSORT
(PERSON_LAST_NAME, 'NLS_SORT=BINARY_CI')
)
;
Esta información fue tomada de búsquedas insensibles a mayúsculas y minúsculas de Oracle . El artículo menciona, REGEXP_LIKE
pero parece funcionar con buenos viejos =
también.
En versiones anteriores a 10gR2, realmente no se puede hacer y el enfoque habitual, si no necesita una búsqueda insensible al acento , es solo UPPER()
la columna y la expresión de búsqueda.
LIKE
expresiones arbitrarias (p WHERE foo LIKE '%abc%'
. Ej. ) Ya son lo suficientemente lentas si no pueden indexarse, no creo que esté específicamente relacionado con mayúsculas y minúsculas.
DBD::Oracle
, puede escribir $ENV{NLS_SORT} = 'BINARY_CI'; $ENV{NLS_COMP} = 'LINGUISTIC';
antes de llamar a `DBI-> connect`.
ALTER SESSION
solo altera su instancia local de la corrección y significa que es como su sesión actual, es decir, si cierro y vuelvo a abrir, se habría restablecido. ¿Hay alguna manera de que pueda ver cuáles son los valores actuales para que si persiste en todas partes pueda volver a la configuración original ...
Hay 3 formas principales de realizar una búsqueda sin distinción entre mayúsculas y minúsculas en Oracle sin usar índices de texto completo.
En última instancia, el método que elija depende de sus circunstancias individuales; Lo principal que debe recordar es que para mejorar el rendimiento debe indexar correctamente las búsquedas que no distinguen entre mayúsculas y minúsculas.
Puede forzar que todos sus datos sean el mismo caso usando UPPER()
o LOWER()
:
select * from my_table where upper(column_1) = upper('my_string');
o
select * from my_table where lower(column_1) = lower('my_string');
Si column_1
no está indexado upper(column_1)
o lower(column_1)
, según corresponda, esto puede forzar un escaneo completo de la tabla. Para evitar esto, puede crear un índice basado en funciones .
create index my_index on my_table ( lower(column_1) );
Si usa LIKE, debe concatenar una %
cadena alrededor de la cadena que está buscando.
select * from my_table where lower(column_1) LIKE lower('my_string') || '%';
Este SQL Fiddle demuestra lo que sucede en todas estas consultas. Tenga en cuenta los planes de explicación, que indican cuándo se utiliza un índice y cuándo no.
A partir de Oracle 10g en adelante REGEXP_LIKE()
está disponible. Puede especificar _match_parameter_ 'i'
para realizar búsquedas que no distinguen entre mayúsculas y minúsculas.
Para usar esto como un operador de igualdad, debe especificar el inicio y el final de la cadena, que se denota por el quilate y el signo de dólar.
select * from my_table where regexp_like(column_1, '^my_string$', 'i');
Para realizar el equivalente de LIKE, estos se pueden eliminar.
select * from my_table where regexp_like(column_1, 'my_string', 'i');
Tenga cuidado con esto ya que su cadena puede contener caracteres que serán interpretados de manera diferente por el motor de expresión regular.
Este Fiddle de SQL le muestra el mismo resultado de ejemplo, excepto que usa REGEXP_LIKE ().
El parámetro NLS_SORT gobierna la secuencia de clasificación para ordenar y los diversos operadores de comparación, incluidos =
y LIKE. Puede especificar un orden binario, sin distinción entre mayúsculas y minúsculas, ordenando alterando la sesión. Esto significará que cada consulta realizada en esa sesión realizará parámetros que no distinguen entre mayúsculas y minúsculas.
alter session set nls_sort=BINARY_CI
Hay mucha información adicional sobre la clasificación lingüística y la búsqueda de cadenas si desea especificar un idioma diferente, o hacer una búsqueda insensible al acento usando BINARY_AI.
También deberá cambiar el parámetro NLS_COMP ; citar:
Los operadores exactos y las cláusulas de consulta que obedecen al parámetro NLS_SORT dependen del valor del parámetro NLS_COMP. Si un operador o cláusula no obedece el valor NLS_SORT, según lo determinado por NLS_COMP, la intercalación utilizada es BINARY.
El valor predeterminado de NLS_COMP es BINARY; pero, LINGUISTIC especifica que Oracle debe prestar atención al valor de NLS_SORT:
Las comparaciones para todas las operaciones SQL en la cláusula WHERE y en los bloques PL / SQL deben usar el tipo lingüístico especificado en el parámetro NLS_SORT. Para mejorar el rendimiento, también puede definir un índice lingüístico en la columna para la que desea realizar comparaciones lingüísticas.
Entonces, una vez más, necesitas alterar la sesión
alter session set nls_comp=LINGUISTIC
Como se señala en la documentación, es posible que desee crear un índice lingüístico para mejorar el rendimiento
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') || '%';
lugar de select * from my_table where lower(column_1) LIKE lower('my_string%');
? ¿Le da alguna ventaja?
regexp_like
, ¿hay alguna forma de escapar de tales cadenas? Dando un ejemplo, si la cadena tiene $, la salida no será la que esperamos. // cc @Ben y otros, por favor comparte.
`
es el personaje de escape @bozzmob. No debería haber ninguna diferencia en la salida si la cadena en la que opera la expresión regular contiene a $
, esto solo puede causar problemas si necesita un $
literal en su expresión regular. Si tiene un problema específico, haría otra pregunta si este comentario / respuesta no ha ayudado.
tal vez puedas intentar usar
SELECT user_name
FROM user_master
WHERE upper(user_name) LIKE '%ME%'
WHERE upper(user_name) LIKE UPPER('%ME%')
entonces? :)
UPPER
también el parámetro de entrada?
upper
función pierde el índice, ¿tiene alguna idea de cómo hacer una búsqueda usando el índice?
Desde Oracle 12c R2 puedes usar COLLATE operator
:
El operador COLLATE determina la clasificación para una expresión. Este operador le permite anular la clasificación que la base de datos habría derivado para la expresión utilizando reglas de derivación de clasificación estándar.
El operador COLLATE toma un argumento, collation_name, para el que puede especificar una colación con nombre o una pseudocolación. Si el nombre de intercalación contiene un espacio, debe encerrarlo entre comillas dobles.
Manifestación:
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 en el primer argumento a su segundo noNLSSORT
están destinados a ser comodines, ¿verdad? Se confunden un poco.