Dans le documentation sur l'opérateur LIKE , rien n'est dit sur sa sensibilité à la casse. Est-ce Comment l'activer/le désactiver?
J'interroge les colonnes varchar(n)
, sur une installation de Microsoft SQL Server 2005, si cela compte.
Ce n'est pas l'opérateur qui respecte la casse, c'est la colonne elle-même.
Lorsqu'une installation SQL Server est effectuée, un classement par défaut est choisi pour l'instance. Sauf mention explicite contraire (consultez la clause collate ci-dessous), lors de la création d'une nouvelle base de données, celle-ci hérite du classement de l'instance et, lorsqu'une nouvelle colonne est créée, du classement de la base de données à laquelle elle appartient.
Une collation comme sql_latin1_general_cp1_ci_as
_ détermine comment le contenu de la colonne doit être traité. CI signifie insensible à la casse et AS signifie insensible aux accents.
Une liste complète des classements est disponible à l'adresse https://msdn.Microsoft.com/en-us/library/ms144250 (v = sql.105) .aspx
(a) Vérifier le classement d'une instance
select serverproperty('collation')
(b) Pour vérifier un classement de base de données
select databasepropertyex('databasename', 'collation') sqlcollation
(c) Pour créer une base de données en utilisant un classement différent
create database exampledatabase
collate sql_latin1_general_cp1_cs_as
(d) Pour créer une colonne en utilisant un classement différent
create table exampletable (
examplecolumn varchar(10) collate sql_latin1_general_cp1_ci_as null
)
(e) Modifier un classement de colonne
alter table exampletable
alter column examplecolumn varchar(10) collate sql_latin1_general_cp1_ci_as null
Il est possible de modifier les classements d'une instance et d'une base de données, mais cela n'affecte pas les objets créés précédemment.
Il est également possible de modifier un classement de colonne à la volée pour la comparaison de chaînes, mais cela n’est pas recommandé dans un environnement de production car il est extrêmement coûteux.
select
column1 collate sql_latin1_general_cp1_ci_as as column1
from table1
Toutes ces discussions sur la collation semblent un peu compliquées. Pourquoi ne pas simplement utiliser quelque chose comme:
IF UPPER(@@VERSION) NOT LIKE '%Azure%'
Ensuite, votre chèque est insensible à la casse quel que soit le classement
Vous avez la possibilité de définir un ordre de classement lors de la définition de votre table. Si vous définissez un ordre sensible à la casse, votre opérateur LIKE
se comportera de manière sensible à la casse; si vous définissez un ordre de classement ne respectant pas la casse, l'opérateur LIKE
ignorera également la casse:
CREATE TABLE Test (
CI_Str VARCHAR(15) COLLATE Latin1_General_CI_AS -- Case-insensitive
, CS_Str VARCHAR(15) COLLATE Latin1_General_CS_AS -- Case-sensitive
);
Voici un démonstration rapide sur sqlfiddle montrant les résultats de l'ordre de classement lors de recherches avec LIKE
.
Si vous souhaitez effectuer une recherche sensible à la casse sans changer le classement de la colonne/base de données/serveur, vous pouvez toujours utiliser la clause COLLATE
, par exemple.
USE tempdb;
GO
CREATE TABLE dbo.foo(bar VARCHAR(32) COLLATE Latin1_General_CS_AS);
GO
INSERT dbo.foo VALUES('John'),('john');
GO
SELECT bar FROM dbo.foo
WHERE bar LIKE 'j%';
-- 1 row
SELECT bar FROM dbo.foo
WHERE bar COLLATE Latin1_General_CI_AS LIKE 'j%';
-- 2 rows
GO
DROP TABLE dbo.foo;
Fonctionne dans l'autre sens également, si votre colonne/base de données/serveur est sensible à la casse et que vous ne souhaitez pas effectuer de recherche sensible à la casse, par exemple.
USE tempdb;
GO
CREATE TABLE dbo.foo(bar VARCHAR(32) COLLATE Latin1_General_CI_AS);
GO
INSERT dbo.foo VALUES('John'),('john');
GO
SELECT bar FROM dbo.foo
WHERE bar LIKE 'j%';
-- 2 rows
SELECT bar FROM dbo.foo
WHERE bar COLLATE Latin1_General_CS_AS LIKE 'j%';
-- 1 row
GO
DROP TABLE dbo.foo;
L'opérateur like
prend deux chaînes. Ces chaînes doivent avoir des classements compatibles, ce qui est expliqué ici .
À mon avis, les choses se compliquent ensuite. La requête suivante renvoie une erreur indiquant que les classements sont incompatibles:
select *
from INFORMATION_SCHEMA.TABLES
where 'abc' COLLATE SQL_Latin1_General_CP1_CI_AS like 'ABC' COLLATE SQL_Latin1_General_CP1_CS_AS
Sur une machine aléatoire ici, le classement par défaut est SQL_Latin1_General_CP1_CI_AS
. La requête suivante est réussie, mais ne renvoie aucune ligne:
select *
from INFORMATION_SCHEMA.TABLES
where 'abc' like 'ABC' COLLATE SQL_Latin1_General_CP1_CS_AS
Les valeurs "abc" et "ABC" ne correspondent pas dans un monde sensible à la casse.
En d'autres termes, il existe une différence entre ne pas avoir de classement et utiliser le classement par défaut. Lorsqu'un côté n'a pas de classement, il se voit attribuer un classement explicite de l'autre côté.
(Les résultats sont les mêmes lorsque le classement explicite est à gauche.)
Essayez de courir,
SELECT SERVERPROPERTY('COLLATION')
Recherchez ensuite si votre classement est sensible à la casse ou non.
Vous pouvez facilement modifier le classement dans Microsoft SQL Server Management Studio.