Почему разные строки, которые отличаются только регистром, одинаковы в версии SQL Server 15.0.4033.1?

#sql-server

#sql-server

Вопрос:

Когда я использую этот код в качестве теста:

 declare @s1 varchar(100) set @s1 = 'AABA/2AA2AAA6YBAAc'
declare @s2 varchar(100) set @s2 = 'AABA/2AA2AAA6YBAAC'
IF
@s1=@s2
BEGIN
    PRINT 'Same'
END
ELSE
BEGIN
    PRINT 'Not Same'
END
  

Результат «Тот же». Что для меня звучит странно, потому что s1 и s2 разные (см. Последний символ c и C).

Почему SQL Server сообщает мне, что они одинаковы?

Ответ №1:

Параметры сортировки. Вы явно используете параметры сортировки без учета регистра, поэтому прописные и строчные буквы рассматриваются как одинаковые для операций сравнения. Если вы не хотите, чтобы разные значения регистра отображались одинаково, используйте параметры сортировки с учетом регистра.

Например, в приведенном ниже примере я изменяю параметры сортировки переменной @s2 в IF . Если это была таблица, вы можете захотеть изменить определение столбца:

 DECLARE @s1 varchar(100);
SET @s1 = 'AABA/2AA2AAA6YBAAc' 
DECLARE @s2 varchar(100);
SET @s2 = 'AABA/2AA2AAA6YBAAC'
IF @s1=@s2 COLLATE SQL_Latin1_General_CP1_CS_AS BEGIN
    PRINT 'Same'
END ELSE BEGIN
    PRINT 'Not Same'
END
  

Ответ №2:

Это зависит от сортировки.

Чтобы узнать, какая сортировка находится в контексте вашей базы данных, запросите :

 SELECT DATABASEPROPERTYEX(DB_NAME(), 'Collation')
  

CI указывает, что регистр не чувствителен.

Комментарии:

1. Концепция СОРТИРОВКИ пришла из стандартного SQL с 1986 года и относится к регистру (CI / CS) или чувствительности к диакритическим знакам (AS / ASI — акценты, лигатуры …), широкому набору символов и некоторым другим функциям для некоторых национальных языков (например, типы канатов при использовании японского алфавита)… MS SQL Sever имеет около 5000 различных параметров сортировки.

2. Сейчас в SQL Server 2019 их более 5500; было добавлено много из-за новых параметров сортировки UTF8.

Ответ №3:

Это потому, что он не чувствителен к регистру, вы можете попробовать этот простой подход для достижения ваших требований с помощью приведенного ниже кода :

 declare @s1 varchar(100) set @s1 = 'AABA/2AA2AAA6YBAAc'
declare @s2 varchar(100) set @s2 = 'AABA/2AA2AAA6YBAAC'
IF HASHBYTES('sha1', @s1)=HASHBYTES('sha1', @s2)
BEGIN
    PRINT 'Same'
END
ELSE
BEGIN
    PRINT 'Not Same'
END
  

Этот код использует для этого хэшбайты.

Комментарии:

1. Было бы более семантичным использовать двоичную сортировку, а не использовать HASHBYTES для выполнения двоичного сопоставления

2. Более понятным будет: ЕСЛИ (a) s1 = (a)s2 СОПОСТАВИТЬ Latin1_General_100_CS_AS