Comment puis-je construire une requête SQL (MS SQL Server) dans laquelle la clause «where» est insensible à la casse?
SELECT * FROM myTable WHERE myField = 'sOmeVal'
Je veux que les résultats reviennent en ignorant le cas
sql
sql-server
where-clause
case-insensitive
Raul Agrait
la source
la source
WHERE
déclaration, et affectera toutes lesWHERE
clauses, n'est-ce pas?UPPER
ou enLOWER
cas, puis en utilisant laLIKE
recherche?En règle générale, les comparaisons de chaînes ne sont pas sensibles à la casse. Si votre base de données est configurée pour un classement sensible à la casse, vous devez forcer à utiliser un classement insensible à la casse:
SELECT balance FROM people WHERE email = '[email protected]' COLLATE SQL_Latin1_General_CP1_CI_AS
la source
J'ai trouvé une autre solution ailleurs; c'est-à-dire utiliser
mais tout le monde ici dit que, dans SQL Server, cela n'a pas d'importance car il ignore de toute façon la casse? Je suis presque sûr que notre base de données est sensible à la casse.
la source
Les 2 premières réponses (d' Adam Robinson et Andrejs Cainikovs ) sont un peu, plutôt correctes, en ce sens qu'elles fonctionnent techniquement, mais leurs explications sont erronées et pourraient donc être trompeuses dans de nombreux cas. Par exemple, bien que le
SQL_Latin1_General_CP1_CI_AS
classement fonctionne dans de nombreux cas, il ne doit pas être supposé être le classement insensible à la casse approprié. En fait, étant donné que l'OP fonctionne dans une base de données avec un classement sensible à la casse (ou éventuellement binaire), nous savons que l'OP n'utilise pas le classement par défaut pour tant d'installations (en particulier celles installées sur un OS en utilisant l' anglais américain comme langue):SQL_Latin1_General_CP1_CI_AS
. Bien sûr, l'OP pourrait utiliserSQL_Latin1_General_CP1_CS_AS
, mais lorsque vous travaillez avecVARCHAR
données, il est important de ne pas changer la page de codes car cela pourrait entraîner une perte de données, et cela est contrôlé par la langue / la culture du classement (c'est-à-dire Latin1_General vs French vs Hebrew, etc.). Veuillez consulter le point 9 ci-dessous.Les quatre autres réponses sont fausses à 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.
Ne l'utilisez pas
UPPER()
. C'est un travail supplémentaire complètement inutile. Utilisez uneCOLLATE
clause. Une comparaison de chaînes doit être effectuée dans les deux cas, mais l'utilisationUPPER()
doit également vérifier, caractère par caractère, s'il existe un mappage en majuscules, puis le modifier. Et vous devez le faire des deux côtés. L'ajout demandeCOLLATE
simplement au traitement de générer les clés de tri en utilisant un ensemble de règles différent de celui auquel il était destiné par défaut. L'utilisationCOLLATE
est nettement plus efficace (ou "performante", si vous aimez ce mot :) que l'utilisationUPPER()
, comme le prouve ce script de test (sur PasteBin) .Il y a aussi le problème noté par @Ceisc sur la réponse de @ Danny:
La majuscule turque "İ" est l'exemple courant.
Non, le classement n'est pas un paramètre à l'échelle de la 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, et il est utilisé par défaut pour les colonnes modifiées et nouvellement créées qui ne spécifient pas la
COLLATE
clause (ce qui est probablement la source de cette idée fausse commune), mais elle n'a pas d'incidence directe sur les requêtes, sauf si vous êtes comparer des littéraux de chaîne et des variables à d'autres littéraux de chaîne et variables, ou vous faites référence à des métadonnées au niveau de la base de données.Non, le classement n'est pas par requête.
Les classements sont par prédicat (c'est-à-dire quelque chose d'opérande) ou expression, pas par requête. Et cela est vrai pour l'ensemble de la requête, pas seulement pour la
WHERE
clause. Cela couvre les JOINs, GROUP BY, ORDER BY, PARTITION BY, etc.Non, ne pas convertir en
VARBINARY
(par exempleconvert(varbinary, myField) = convert(varbinary, 'sOmeVal')
) pour les raisons suivantes:_BIN2
si vous utilisez SQL Server 2008 ou plus récent, sinon vous n'avez pas d'autre choix que d'en utiliser un qui se termine par_BIN
. Si les données le sont,NVARCHAR
peu importe la langue que vous utilisez, car elles sont toutes identiques dans ce cas, elles fonctionnent doncLatin1_General_100_BIN2
toujours. Si les donnéesVARCHAR
, vous devez utiliser les mêmes paramètres régionaux que les données sont actuellement (par exempleLatin1_General
,French
,Japanese_XJIS
, etc.) parce que les paramètres régionaux détermine la page de code qui est utilisé, et la modification des pages de code peut modifier les données (perte de données).CONVERT()
il utilisera la valeur par défaut 30. Le danger est que si la chaîne peut dépasser 30 octets, elle sera silencieusement tronquée et vous obtiendrez probablement des résultats incorrects de ce prédicat.Non,
LIKE
n'est pas toujours sensible à la casse. Il utilise le classement de la colonne référencée, ou le classement de la base de données si une variable est comparée à un littéral de chaîne, ou le classement spécifié via laCOLLATE
clause facultative .LCASE
n'est pas une fonction SQL Server. Il semble que ce soit Oracle ou MySQL. Ou peut-être Visual Basic?Étant donné que le contexte de la question compare une colonne à un littéral de chaîne, ni le classement de l'instance (souvent appelé «serveur») ni le classement de la base de données n'ont ici d'impact direct . Les classements sont stockés pour chaque colonne et chaque colonne peut avoir un classement différent, et ces classements n'ont pas besoin d'être les mêmes que le classement par défaut de la base de données ou le classement de l'instance. Bien sûr, le classement des instances est le classement par défaut de ce qu'une base de données nouvellement créée utilisera comme classement par défaut si la
COLLATE
clause n'a pas été spécifiée lors de la création de la base de données. Et de même, le classement par défaut de la base de données est ce qu'une colonne modifiée ou nouvellement créée utilisera si laCOLLATE
clause n'a pas été spécifiée.Vous devez utiliser le classement insensible à la casse qui est sinon le même que le classement de la colonne. Utilisez la requête suivante pour trouver le classement de la colonne (modifiez le nom de la table et le nom du schéma):
SELECT col.* FROM sys.columns col WHERE col.[object_id] = OBJECT_ID(N'dbo.TableName') AND col.[collation_name] IS NOT NULL;
Ensuite, changez simplement le
_CS
pour être_CI
. Alors,Latin1_General_100_CS_AS
deviendraitLatin1_General_100_CI_AS
.Si la colonne utilise un classement binaire (se terminant par
_BIN
ou_BIN2
), recherchez un classement similaire à l'aide de la requête suivante:SELECT * FROM sys.fn_helpcollations() col WHERE col.[name] LIKE N'{CurrentCollationMinus"_BIN"}[_]CI[_]%';
Par exemple, en supposant que la colonne utilise
Japanese_XJIS_100_BIN2
, procédez comme suit:SELECT * FROM sys.fn_helpcollations() col WHERE col.[name] LIKE N'Japanese_XJIS_100[_]CI[_]%';
Pour plus d' informations sur les classements, codages, etc., visitez s'il vous plaît: collation Infos
la source
Non, seule l'utilisation
LIKE
ne fonctionnera pas.LIKE
recherche des valeurs correspondant exactement à votre modèle donné. Dans ce casLIKE
, trouverait uniquement le texte «sOmeVal» et non «someval».Une solution pratique consiste à utiliser la
LCASE()
fonction.LCASE('sOmeVal')
obtient la chaîne 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 minuscules, de sorte que votre 'sOmeVal' correspondra à toutes les autres notations de 'someval' (par exemple 'Someval', 'sOMEVAl' etc.).
la source
LCASE()
dans SQL Server (du moins pas que je puisse voir). Je pense que cette réponse est pour un SGBDR entièrement différent. Veuillez consulter ma réponse pour obtenir des précisions sur les comparaisons de chaînes.Vous pouvez forcer la sensibilité à la casse, en effectuant un cast en varbinary comme ça:
SELECT * FROM myTable WHERE convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
la source
Sur quelle base de données êtes-vous? Avec MS SQL Server, il s'agit d'un paramètre à l'échelle de la base de données, ou vous pouvez le remplacer par requête avec le mot clé COLLATE.
la source