web-dev-qa-db-fra.com

L'opérateur LIKE est-il sensible à la casse avec MSSQL Server?

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.

85
Marcel

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
87
lolol

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

15
Phil R

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.

14
dasblinkenlight

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;
11
Aaron Bertrand

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.)

5
Gordon Linoff

Essayez de courir,

SELECT SERVERPROPERTY('COLLATION')

Recherchez ensuite si votre classement est sensible à la casse ou non.

3
RandomUs1r

Vous pouvez modifier la propriété de chaque élément.

case sensitive

1
Daniel Cadena

Vous pouvez facilement modifier le classement dans Microsoft SQL Server Management Studio.

  • table de clic droit -> design.
  • choisissez votre colonne, faites défiler les propriétés de la colonne jusqu’à Collation.
  • Définissez votre préférence de tri en cochant "Case Sensitive"
0