Question

Comment puis-je construire une requête SQL (MS SQL Server) où le " where " clause est-elle sensible à la casse?

SELECT * FROM myTable WHERE myField = 'sOmeVal'

Je veux que les résultats reviennent en ignorant le cas

Était-ce utile?

La solution

Dans la configuration par défaut d'une base de données SQL Server, les comparaisons de chaînes sont sensibles à la casse. Si votre base de données remplace ce paramètre (par le biais d'un classement alternatif), vous devrez spécifier le type de classement à utiliser dans votre requête.

SELECT * FROM myTable WHERE myField = 'sOmeVal' COLLATE SQL_Latin1_General_CP1_CI_AS

Notez que le classement que j’ai fourni n’est qu’un exemple (bien qu’il fonctionne probablement très bien pour vous). Vous trouverez un aperçu plus détaillé des classements de SQL Server ici .

Autres conseils

Habituellement, les comparaisons de chaînes ne sont pas sensibles à la casse. Si votre base de données est configurée pour le classement sensible à la casse, vous devez forcer l'utilisation d'un nom ne respectant pas la casse:

SELECT balance FROM people WHERE email = 'billg@microsoft.com'
  COLLATE SQL_Latin1_General_CP1_CI_AS 

j'ai trouvé une autre solution ailleurs; c'est-à-dire utiliser

upper(@yourString)

mais tout le monde ici dit que, dans SQL Server, ça n'a pas d'importance, parce que c'est de toute façon un cas ignoré? Je suis presque sûr que notre base de données est sensible à la casse.

Non, utiliser uniquement LIKE ne fonctionnera pas. LIKE recherche les valeurs correspondant exactement à votre modèle donné. Dans ce cas, LIKE ne trouverait que le texte "sOmeVal" et non "someval".

Une solution pracitcable utilise la fonction LCASE () . LCASE ('sOmeVal') obtient la chaîne en minuscule de votre texte: 'someval'. Si vous utilisez cette fonction pour les deux côtés de votre comparaison, cela fonctionne:

SELECT * FROM myTable WHERE LCASE (myField) LIKE LCASE ('sOmeVal')

L'instruction compare deux chaînes en minuscules, de sorte que votre "sOmeVal" corresponde à toutes les autres notations de "someval" (par exemple, "Someval", "sOMEVAl", etc.).

Les deux principales réponses (tirées de Adam Robinson et Andrejs Cainikovs ) sont en quelque sorte corrects, dans la mesure où ils fonctionnent techniquement, mais leurs explications sont fausses et peuvent donc être trompeuses dans de nombreux cas. Par exemple, bien que le classement SQL_Latin1_General_CP1_CI_AS fonctionne dans de nombreux cas, il ne doit pas être considéré comme étant le classement ne tenant pas compte de la casse. En fait, étant donné que l’OP travaille dans une base de données avec un classement sensible à la casse (ou éventuellement binaire), nous savons qu’il n’utilise pas le classement qui est celui par défaut pour de nombreuses installations (en particulier celles installées sur un système d’exploitation). utilisant l’anglais américain comme langue): SQL_Latin1_General_CP1_CI_AS . Bien sûr, l'OP pourrait utiliser SQL_Latin1_General_CP1_CS_AS , mais lorsque vous utilisez des données VARCHAR , il est important de ne pas modifier la page de code car cela pourrait entraîner à la perte de données, et qui est contrôlé par la localisation / culture de la collation (c'est-à-dire Latin1_General vs French vs Hebrew etc.). Veuillez vous reporter au point 9 ci-dessous.

Les quatre autres réponses sont erronées à des degrés divers.

Je vais clarifier tous les malentendus ici afin que les lecteurs puissent, espérons-le, faire les choix les plus appropriés / efficaces.

  1. N'utilisez pas UPPER () . C'est un travail supplémentaire totalement inutile. Utilisez une clause COLLATE . Une comparaison de chaînes doit être effectuée dans les deux cas, mais l'utilisation de UPPER () doit également vérifier, caractère par caractère, pour voir s'il existe un mappage en majuscules, puis le modifier. Et vous devez le faire des deux côtés. L'ajout de COLLATE oblige simplement le traitement à générer les clés de tri à l'aide d'un ensemble de règles différent de celui par défaut. Utiliser COLLATE est nettement plus efficace (ou "performant", si vous aimez ce mot :) que d'utiliser UPPER () , comme le prouve ce script de test (sur PasteBin) .

    Il existe également le problème signalé par @Ceisc le @ La réponse de Danny:

      

    Dans certaines langues, les conversions ne sont pas aller-retour. i.e. LOWER (x)! = LOWER (UPPER (x)).

    Les majuscules turques " I " est l'exemple commun.

  2. Non, le classement n'est pas un paramètre de base de données, du moins pas dans ce contexte. Il existe un classement par défaut au niveau de la base de données, qui est utilisé par défaut pour les colonnes modifiées et nouvellement créées qui ne spécifient pas la clause COLLATE (qui est probablement l'origine de cette idée fausse courante), mais n'a pas d'impact direct sur les requêtes, sauf si vous comparez des littéraux de chaîne et des variables avec d'autres littéraux de chaîne et des variables, ou si vous référencez des métadonnées au niveau de la base de données.

  3. Non, le classement ne se fait pas par requête.

  4. Les classements sont par prédicat (c'est-à-dire quelque chose d'opérande, quelque chose) ou d'expression, pas par requête. Et ceci est vrai pour toute la requête, pas seulement la clause WHERE . Ceci couvre les jointures, les groupes, les commandes, les partitions, etc.

  5. Non, ne convertissez pas en VARBINARY (par exemple, convert (varbinary, myField) = convert (varbinary, 'sOmeVal') ) pour les raisons suivantes:

    1. c'est une comparaison binaire, qui ne respecte pas la casse (c'est ce que cette question demande)
    2. si vous souhaitez une comparaison binaire, utilisez un classement binaire. Utilisez celui qui se termine par _BIN2 si vous utilisez SQL Server 2008 ou une version plus récente, sinon vous n’avez pas d’autre choix que d’en utiliser un qui se termine par _BIN . Si les données sont NVARCHAR , le paramètre régional que vous utilisez n'a pas d'importance

Vous pouvez forcer la distinction entre les majuscules et les minuscules, en utilisant un varbinary comme celui-ci:

SELECT * FROM myTable 
WHERE convert(varbinary, myField) = convert(varbinary, 'sOmeVal')

Sur quelle base de données êtes-vous? Avec MS SQL Server, il s’agit d’un paramètre couvrant l’ensemble de la base de données. Vous pouvez également le remplacer par requête à l’aide du mot clé COLLATE.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top