2009-06-23 3 views
43

Comme je l'avais écrit dans le titre, j'ai requête SQL, exécutez sur Oracle DB, permet de dire:Oracle DB: Comment puis-je écrire une requête ignorant la casse?

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

Si je voudrais que la requête retournerait soit « IGNORECASE », « ignorecase » ou des combinaisons de eux, comment cela peut-il être fait?

Est-ce possible?

+0

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

Répondre

28

Vous pouvez utiliser des instructions ALTER session pour établir la comparaison à la casse. Voir this FAQ.

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

Pour tous ces 8 ans en visite après cette réponse initiale a été acceptée (pour 10gR2):

Après 10gR2, le réglage NLS_COMP doit être `LINGUISTIQUE ':

ALTER SESSION SET NLS_COMP=LINGUISTIC; 
+1

Si zeroDevisible est sur 10gR2 ou supérieur, c'est beaucoup mieux que les index basés sur les fonctions, car il couvrira tous les 12 champs de la requête sans la surcharge de tous ces index. Un problème potentiel est que l'utilisateur doit modifier la session à chaque fois. – akf

+3

Je ne suis pas sûr de ce dont vous parlez. Si vous créez un index "normal", puis modifiez NLS_COMP et NLS_SORT, Oracle ne pourra plus utiliser l'index pour trouver les données en question. Vous finirez donc par créer des index spécifiques au paramètre NLS pour les colonnes appropriées. Ce n'est pas évident pour moi de savoir comment cela génère plus ou moins de frais généraux que les index fonctionnels (FBI). Évidemment, si vous voulez que toutes les requêtes soient insensibles à la casse, il n'y a pas besoin de maintenir un index sur une colonne et un FBI sur UPPER (colonne) (ou de maintenir des index pour différents paramètres NLS) –

+0

Cela fonctionne-t-il pour les caractères Unicode? –

28

Vous pouvez utiliser soit inférieure ou supérieure fonction des deux côtés de l'état où

+0

Merci pour une réponse aussi rapide. Je me demande, parce que ma requête sélectionne environ 12 champs de la table vraiment énorme, donc j'aurais besoin d'environ 20 utilisations de la fonction supérieure - ne serait-ce pas un coup de performance? – zeroDivisible

+0

Si vous connaissez les mots exacts que vous souhaitez vérifier, vous pouvez utiliser une instruction IN (SELECT * FROM TABLE WHERE UPPER (NOM) IN (UPPER ('Name1'), UPPER ('Name2')) ou si les noms tous commencent par la même chose que vous pourriez le faire avec un caractère générique (SELECT * FROM TABLE O WH UPPER (NAME) COMME UPPER ('Search%');) – Hooloovoo

+5

L'utilisation de fonctions comme upper n'est jamais un succès de performance si vous parlez de la temps nécessaire à Oracle pour effectuer l'opération - le temps nécessaire au processeur pour effectuer la conversion est trivial par rapport au temps nécessaire pour charger les pages de données à partir du cache, sans parler de l'extraction à partir du disque. empêchera votre requête d'utiliser des index sur ces colonnes, sauf si vous avez créé des index utilisant ces fonctions.Mais LIKE peut également empêcher l'utilisation d'index, en particulier si le premier caractère de l'expression est un caractère générique. –

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

Vous pouvez également remplacer inférieure pour supérieure.

6

Vous pouvez utiliser la fonction supérieure() dans votre requête, et pour augmenter les performances, vous pouvez utiliser un index fonction de base

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

... également effectuer la conversion en haut ou en bas de la requête:

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

...

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

Vous pouvez également utiliser les expressions régulières:

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

Aussi ne pas oublier l'évidence, que les données d'dans les tableaux doivent avoir le cas? Vous pouvez seulement insérer des lignes déjà en minuscules (ou convertir les lignes de DB existantes en minuscules) et être fait avec dès le début.

+0

c'est un problème si vous avez des noms propres. Surtout si vous avez des noms propres et non-propres dans le même champ. – kralco626

3

Vous pouvez convertir des valeurs majuscules ou minuscules en utilisant les upper ou lower fonctions:

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

C'est probablement la bonne réponse, mais notez que cela pourrait casser toute indexation que vous avez sur vos chaînes. Si vous avez besoin d'indexation, vous pouvez ajouter une nouvelle colonne dans laquelle vous insérez toujours la valeur normalisée par la casse. – wjl

+0

Pourquoi le 'ou'? Est-il possible que les majuscules correspondent mais que les minuscules ne correspondent pas? –

+3

Je pense @ user3666177 posté le 'ou' pour démontrer les deux options. Je ne pense pas qu'il soit possible de faire correspondre mais pas l'autre. – wjl

Questions connexes