2009-06-23 11 views
43

Come avevo scritto nel titolo, ho query SQL, eseguito su DB Oracle, consente di dire:DB Oracle: come posso scrivere query ignorando il caso?

SELECT * FROM TABLE WHERE TABLE.NAME Like 'IgNoReCaSe' 

Se mi piacerebbe, che la query restituirebbe sia "IGNORECASE", "ignorecase", o combinazioni di loro, come può essere fatto?

È possibile?

+0

http://stackoverflow.com/questions/5391069/case-insensitive-searching-in-oracle – zloctb

risposta

28

È possibile utilizzare le istruzioni ALTER SESSION per impostare il confronto di maiuscole e minuscole. Vedi this FAQ.

alter session set NLS_COMP=ANSI; 
alter session set NLS_SORT=BINARY_CI; 

Per tutti coloro che visitano 8 anni dopo questa risposta originale è stato accettato (per 10gR2):

Dopo 10gR2, l'impostazione NLS_COMP deve essere `LINGUISTICA ':

ALTER SESSION SET NLS_COMP=LINGUISTIC; 
+1

se zeroDevisible è su 10gR2 o superiore, questo è molto meglio degli indici basati sulle funzioni, poiché coprirà tutti i 12 campi della query senza il sovraccarico di tutti quegli indici. un potenziale problema è che l'utente deve modificare la sessione ogni volta. – akf

+3

Non sono sicuro di quale overhead stai parlando. Se si crea un indice "normale", quindi si modificano NLS_COMP e NLS_SORT, Oracle non sarà più in grado di utilizzare l'indice per trovare i dati in questione. Quindi si finirebbe con la creazione di indici specifici delle impostazioni NLS per qualsiasi colonna sarebbe appropriata. Non è ovvio per me come ciò generi un sovraccarico maggiore o minore rispetto agli indici basati sulle funzioni (FBI). Ovviamente, se si desidera che tutte le query non siano sensibili al maiuscolo/minuscolo, non è necessario mantenere un indice su una colonna e un FBI su UPPER (colonna) (o per mantenere indici per diverse impostazioni NLS) –

+0

Funziona con caratteri unicode? –

28

È possibile utilizzare la funzione sia inferiore o superiore su entrambi i lati del quale condizione

+0

Grazie per una risposta così veloce Mi chiedo, perché la mia query seleziona circa 12 campi da una tabella veramente enorme, quindi avrei bisogno di circa 20 usi della funzione superiore - non sarebbe un successo in termini di prestazioni? – zeroDivisible

+0

Se si conoscono le parole esatte da controllare, è possibile utilizzare un'istruzione IN (SELECT * FROM TABLE WHERE UPPER (NAME) IN (UPPER ('Name1'), UPPER ('Name2')) o se i nomi tutto inizia lo stesso si potrebbe fare con un carattere jolly (SELECT * FROM TABLE WHERE UPPER (NAME) LIKE UPPER ('Cerca%');) – Hooloovoo

+5

L'uso di funzioni come la tomaia non è mai un successo in termini di prestazioni se si parla di tempo impiegato da Oracle per eseguire l'operazione - il tempo impiegato dalla cpu per eseguire la conversione è insignificante rispetto al tempo necessario per caricare le pagine di dati dalla cache, non importa se lo si preleva dal disco. impedirà alla query di utilizzare qualsiasi indice su tali colonne, a meno che non abbiate creato indici che usassero tali funzioni.Ma LIKE potrebbe anche prevenire l'uso dell'indice, in particolare se il primo carattere nell'espressione è un carattere jolly. –

96
Select * from table where upper(table.name) like upper('IgNoreCaSe'); 

alternativa, sostituire inferiore per superiore.

6

È possibile utilizzare la funzione superiore() nella query, e per aumentare le prestazioni è possibile utilizzare un indice di funzione di base

CREATE INDEX upper_index_name ON table(upper(name)) 
3

... effettuare anche la conversione al di sopra o al di sotto della query:

tableName:= UPPER(someValue || '%'); 

...

Select * from table where upper(table.name) like tableName 
9

Si potrebbe anche usare espressioni regolari:

SELECT * FROM TABLE WHERE REGEXP_LIKE (TABLE.NAME,'IgNoReCaSe','i'); 
0

Inoltre, non dimenticare l'ovvio, fa i dati nelle tabelle devono avere caso? È possibile inserire solo le righe già in minuscolo (o convertire le righe del DB esistenti in minuscole) e farle fin dall'inizio.

+0

questo è un problema se si dispone di nomi propri. In particolare se si hanno sia nomi propri che non propri nello stesso campo. – kralco626

3

È possibile convertire entrambi i valori superiori o minuscole utilizzando i upper o lower funzioni:

Select * from table where upper(table.name) like upper('IgNoreCaSe') or lower(table.name) like lower('IgNoreCaSe'); 
+0

Questa è probabilmente la risposta giusta ma si noti che potrebbe interrompere qualsiasi indicizzazione presente sulle stringhe. Se hai bisogno di indicizzazione potresti voler aggiungere una nuova colonna in cui inserisci sempre il valore normalizzato del caso. – wjl

+0

Perché il 'o'? È possibile che le lettere maiuscole corrispondano, ma le lettere minuscole non corrispondono? –

+3

Penso che @ user3666177 abbia pubblicato 'o' per dimostrare entrambe le opzioni. Non penso sia possibile per uno abbinare ma non l'altro. – wjl

Problemi correlati