Сегодня я столкнулся с некоторым интересным поведением на SQL Server (наблюдавшемся в 2005 и 2012 годах), которое, я надеялся, кто-нибудь сможет объяснить.
Запрос, выполняющий сравнение с =
использованием поля NVARCHAR, игнорировал конечный пробел в строке (или автоматически обрезал значение перед сравнением), но тот же запрос с использованием like
оператора не игнорировал этот пробел. Используемая сортировка - Latin1_General_CI_AS в 2012 году.
Рассмотрим эту скрипту SQL: http://sqlfiddle.com/#!6/72262/4
Обратите внимание, что like
оператор не возвращает результат для строки завершающего пробела, но =
оператор возвращает . Почему это?
Бонусные баллы: я не могу повторить это в поле VARCHAR, я бы подумал, что пробел будет обрабатываться одинаково в обоих типах данных - это правда?
MyString+'x' = ltrim(rtrim(MyString))+'x'
как предложено в этом блогеОтветы:
Мой первоначальный ответ предполагал, что флаг ANSI_PADDING, установленный в OFF, может быть виноват в разнице в поведении. Однако это неверно; этот флаг влияет только на хранилище, но не на сравнение равенства.
Разница заключается в реализации Microsoft стандарта SQL . Стандарт гласит, что при проверке на равенство обе строки слева и справа от оператора равенства должны иметь одинаковую длину . Это объясняет следующие результаты:
Оператор LIKE не дополняет свои операнды. Он также ведет себя по- разному для
VARCHAR
иNVARCHAR
типов столбцов :Поведение оператора LIKE для типа ASCII зависит от SQL Server; для типа Unicode это ANSI-совместимый.
источник
SQL родился в эпоху, когда большинство языков обработки данных использовали фиксированные длины для каждого поля / переменной. Автоматическое заполнение текстовых полей дополнительными пробелами также было частью этой картины. Чтобы соответствовать этому поведению, исходный тип SQL CHAR был явно определен для его оператора '=', чтобы игнорировать конечные пробелы. (Если вы находите это странным, покажите мне убедительный случай, когда конечные пробелы, добавленные к тексту, имеют реальное реальное деловое значение .)
С тех пор типы SQL CHAR развивались во всех направлениях, но не исключено, что некоторые более современные типы данных все еще унаследовали некоторые характеристики от своих исторических предшественников.
источник
В документации для LIKE (Transact-SQL) Microsoft пишет (выделено мое):
источник