Quel est le meilleur moyen de sélectionner des champs de chaîne en fonction de plages de caractères?

StackOverflow https://stackoverflow.com/questions/152537

Question

Je dois ajouter la possibilité pour les utilisateurs de mon logiciel de sélectionner des enregistrements par plages de caractères.
Comment puis-je écrire une requête qui renvoie tous les widgets d’une table dont le nom se situe dans la plage Ba-Bi par exemple?

Actuellement, j'utilise des opérateurs supérieurs à et inférieurs à des opérateurs. Ainsi, l'exemple ci-dessus deviendrait:

select * from widget
where name >= 'ba' and name < 'bj'

Remarquez comment j'ai " incrémenté " le dernier caractère de la borne supérieure de i à j, de sorte que & "vélo &"; ne serait pas en reste.

Existe-t-il un moyen générique de rechercher le caractère suivant un caractère après le classement du champ ou serait-il plus sûr de créer une deuxième condition?

select * from widget
where name >= 'ba'
and (name < 'bi' or name like 'bi%')

Mon application doit prendre en charge la localisation. Quelle est la sensibilité de ce type de requête à différents jeux de caractères?

Je dois également prendre en charge MSSQL et Oracle. Quelles sont mes options pour faire en sorte que la casse des caractères soit ignorée, quelle que soit la langue utilisée dans les données?

Était-ce utile?

La solution

Passons directement à la localisation. Diriez-vous que & Quot; aa & Quot; > = " ba " ? Probablement pas, mais c'est là que ça se passe en Suède. En outre, vous ne pouvez tout simplement pas présumer que vous pouvez ignorer la casse dans n’importe quelle langue. La casse dépend explicitement de la langue, l'exemple le plus courant étant le turc: la lettre majuscule i est & # 304 ;. I minuscule est & # 305;.

Votre base de données SQL définit le résultat de < ;, == etc. par un " ordre de classement " ;. Ceci est certainement spécifique à la langue. Donc, vous devriez explicitement contrôler cela, pour chaque requête. Un ordre de classement turc mettra ceux qui sont à leur place (en turc). Vous ne pouvez pas compter sur le classement par défaut.

En ce qui concerne & "Increment Part &", ne vous inquiétez pas. S'en tenir à & Gt; = et & Lt; =.

Autres conseils

Frustrement, la fonction de sous-chaîne Oracle est SUBSTR (), alors que SQL-Server est SUBSTRING ().

Vous pouvez écrire un simple wrapper autour d'un ou des deux pour qu'ils partagent le même nom de fonction + prototype.

Ensuite, vous pouvez simplement utiliser

MY_SUBSTRING(name, 2) >= 'ba' AND MY_SUBSTRING(name, 2) <= 'bi'

ou similaire.

Vous pouvez utiliser ceci ...

select * from widget
where name Like 'b[a-i]%'

Ceci correspond à toute ligne dont le nom commence par b, le deuxième caractère est compris entre a et i et tous les autres caractères suivent.

Je pense que je choisirais quelque chose de simple, comme ajouter une chaîne de tri élevé à la fin de la limite supérieure. Quelque chose comme:

select * from widgetwhere name >= 'ba' and name <= 'bi'||'~'

Je ne suis pas sûr que cela survivrait à la conversion EBCDIC bien

Vous pouvez également le faire comme ceci:

select * from widget
where left(name, 2) between 'ba' and 'bi'

Si la longueur de vos critères change (comme vous sembliez l'indiquer dans un commentaire que vous avez laissé), la requête doit également avoir la longueur comme entrée:

declare @CriteriaLength int
set @CriteriaLength = 4
select * from widget
where left(name, @CriteriaLength) between 'baaa' and 'bike'
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top