Il comportamento predefinito di LIKE
e degli altri operatori di confronto, =
ecc. È sensibile al maiuscolo / minuscolo.
È possibile renderli insensibili alle maiuscole / minuscole?
REGEXP_LIKE(username,'me','i')
invece di LIKE?
Il comportamento predefinito di LIKE
e degli altri operatori di confronto, =
ecc. È sensibile al maiuscolo / minuscolo.
È possibile renderli insensibili alle maiuscole / minuscole?
REGEXP_LIKE(username,'me','i')
invece di LIKE?
Risposte:
Da 10gR2, Oracle consente di ottimizzare il comportamento dei confronti di stringhe impostando i parametri 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
Puoi anche creare indici senza distinzione tra maiuscole e minuscole:
create index
nlsci1_gen_person
on
MY_PERSON
(NLSSORT
(PERSON_LAST_NAME, 'NLS_SORT=BINARY_CI')
)
;
Queste informazioni sono state tratte da ricerche senza distinzione tra maiuscole e minuscole Oracle . L'articolo menziona REGEXP_LIKE
ma sembra funzionare anche con il buon vecchio =
.
Nelle versioni precedenti a 10gR2 non si può davvero fare e l'approccio abituale, se non è necessaria una ricerca senza accento accento , è solo UPPER()
la colonna e l'espressione di ricerca.
LIKE
espressioni arbitrarie (ad es. WHERE foo LIKE '%abc%'
) Sono già abbastanza lente se non possono essere indicizzate, non penso che sia specificamente correlato alla sensibilità del caso.
DBD::Oracle
, è possibile scrivere $ENV{NLS_SORT} = 'BINARY_CI'; $ENV{NLS_COMP} = 'LINGUISTIC';
prima di chiamare `DBI-> connect`.
ALTER SESSION
modifica l' unica istanza locale della correzione e significa che è la sessione corrente, cioè se chiudo e riapro avrebbe ripristinato. C'è un modo in cui posso vedere quali sono i valori attuali in modo che se persistesse ovunque posso tornare alle impostazioni originali ...
Esistono 3 modi principali per eseguire una ricerca senza distinzione tra maiuscole e minuscole in Oracle senza utilizzare gli indici full-text.
In definitiva, quale metodo scegli dipende dalle tue circostanze individuali; la cosa principale da ricordare è che per migliorare le prestazioni è necessario indicizzare correttamente la ricerca senza distinzione tra maiuscole e minuscole.
Puoi forzare tutti i tuoi dati nello stesso 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');
Se column_1
non è indicizzato upper(column_1)
o lower(column_1)
, a seconda dei casi, ciò può forzare una scansione completa della tabella. Per evitare ciò, è possibile creare un indice basato sulle funzioni .
create index my_index on my_table ( lower(column_1) );
Se stai usando LIKE, devi concatenare un %
intorno alla stringa che stai cercando.
select * from my_table where lower(column_1) LIKE lower('my_string') || '%';
Questo violino SQL dimostra cosa succede in tutte queste query. Nota i piani esplicativi, che indicano quando viene utilizzato un indice e quando non lo è.
Da Oracle 10g in poi REGEXP_LIKE()
è disponibile. È possibile specificare _match_parameter_ 'i'
, al fine di eseguire ricerche senza distinzione tra maiuscole e minuscole.
Per usarlo come operatore di uguaglianza devi specificare l'inizio e la fine della stringa, che è indicata dal carato e dal simbolo del dollaro.
select * from my_table where regexp_like(column_1, '^my_string$', 'i');
Per eseguire l'equivalente di LIKE, questi possono essere rimossi.
select * from my_table where regexp_like(column_1, 'my_string', 'i');
Fai attenzione poiché la stringa può contenere caratteri che verranno interpretati in modo diverso dal motore delle espressioni regolari.
Questo violino SQL mostra lo stesso output di esempio tranne che per l'utilizzo di REGEXP_LIKE ().
Il parametro NLS_SORT regola la sequenza di confronto per l'ordinamento e i vari operatori di confronto, inclusi =
e LIKE. È possibile specificare un ordinamento binario, senza distinzione tra maiuscole e minuscole, modificando la sessione. Ciò significa che ogni query eseguita in quella sessione eseguirà parametri senza distinzione tra maiuscole e minuscole.
alter session set nls_sort=BINARY_CI
Ci sono molte informazioni aggiuntive sull'ordinamento linguistico e la ricerca di stringhe se si desidera specificare una lingua diversa o eseguire una ricerca senza accento mediante BINARY_AI.
Sarà inoltre necessario modificare il parametro NLS_COMP ; per citare:
Gli operatori esatti e le clausole di query che obbediscono al parametro NLS_SORT dipendono dal valore del parametro NLS_COMP. Se un operatore o una clausola non obbedisce al valore NLS_SORT, come determinato da NLS_COMP, le regole di confronto utilizzate sono BINARY.
Il valore predefinito di NLS_COMP è BINARY; ma LINGUISTIC specifica che Oracle dovrebbe prestare attenzione al valore di NLS_SORT:
I confronti per tutte le operazioni SQL nella clausola WHERE e nei blocchi PL / SQL devono utilizzare l'ordinamento linguistico specificato nel parametro NLS_SORT. Per migliorare le prestazioni, puoi anche definire un indice linguistico sulla colonna per il quale desideri confronti linguistici.
Quindi, ancora una volta, è necessario modificare la sessione
alter session set nls_comp=LINGUISTIC
Come indicato nella documentazione, potresti voler creare un indice linguistico per migliorare le prestazioni
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') || '%';
invece di select * from my_table where lower(column_1) LIKE lower('my_string%');
? Dà qualche vantaggio?
regexp_like
, c'è un modo per sfuggire a tali stringhe? Dando un esempio, se la stringa ha $, l'output non sarà come quello che ci aspettiamo. // cc @Ben e altri per favore condividi.
`
è il carattere di escape @bozzmob. Non dovrebbe esserci alcuna differenza nell'output se la stringa su cui sta funzionando l'espressione regolare contiene un $
, ciò può causare problemi solo se è necessario un valore $
letterale nell'espressione regolare. Se hai un problema specifico, farei un'altra domanda se questo commento / risposta non ha aiutato.
forse puoi provare a usare
SELECT user_name
FROM user_master
WHERE upper(user_name) LIKE '%ME%'
WHERE upper(user_name) LIKE UPPER('%ME%')
allora? :)
UPPER
il parametro di input?
upper
funzione perdi l'indice, hai idea di come effettuare la ricerca utilizzando l'indice?
Da Oracle 12c R2 è possibile utilizzare COLLATE operator
:
L'operatore COLLATE determina le regole di confronto per un'espressione. Questo operatore consente di sovrascrivere le regole di confronto che il database avrebbe derivato per l'espressione utilizzando le regole di derivazione delle regole di confronto standard.
L'operatore COLLATE accetta un argomento, nome_collation, per il quale è possibile specificare una raccolta o una pseudo-raccolta denominata. Se il nome della collation contiene uno spazio, è necessario racchiuderlo tra virgolette doppie.
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')
%
nel primo argomento del secondo nonNLSSORT
sono fatti per essere jolly, giusto? Sono un po 'confusi.