Порожні рядки: Чому або коли '' дорівнює ''?


17

Хто може пояснити, чому

select case when '' = ' ' then 1 else 0 end, LEN(''), LEN(' '), DATALENGTH(''), DATALENGTH(' ');

врожайність

----------- ----------- ----------- ----------- -----------
1           0           0           0           1

Кумедним наслідком цього є те, що в

create table test ( val varchar(10) );
insert into test values( '' );
update test set val = ' ' where val = '';

оновлення дійсно замінить порожній рядок порожнім, але пункт де залишається істинним, і повторне виконання оператора оновлення говорить

(1 row(s) affected)

Відповіді:


22

Пояснення пробілів пояснено :

SQL Server дотримується специфікації ANSI / ISO SQL-92 (Розділ 8.2, Загальні правила №3) щодо порівняння рядків з пробілами. Стандарт ANSI вимагає прокладки для символьних рядків, що використовуються при порівнянні, щоб їх довжини збігалися перед порівнянням. Прокладка безпосередньо впливає на семантику предикатів пункту WHERE і HAVING та інші порівняння рядків Transact-SQL. Наприклад, Transact-SQL вважає рядки 'abc' та 'abc' еквівалентними для більшості операцій порівняння.

Єдиним винятком із цього правила є присудок LIKE. Коли в правій частині виразу предикату LIKE є значення з проміжком проміжку, SQL Server не додає два значення до однакової довжини до початку порівняння. Оскільки метою предиката LIKE за визначенням є полегшення пошуку шаблонів, а не простих тестів рівності рядків, це не порушує згаданий раніше розділ специфікації ANSI SQL-92.

Ось добре відомий приклад усіх випадків, згаданих вище:

DECLARE @a VARCHAR(10)
DECLARE @b varchar(10)

SET @a = '1'
SET @b = '1 ' --with trailing blank

SELECT 1
WHERE 
    @a = @b 
AND @a NOT LIKE @b
AND @b LIKE @a

Ось додаткові відомості про проміжні пробіли та LIKEпункт .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.