Что такое литерал нулевого символа в TSQL? - PullRequest
18 голосов
/ 13 мая 2010

Мне интересно, что литерал для нулевого символа (например, \ 0) в TSQL.

Примечание: не значение поля NULL, а нулевой символ ( см. Ссылку ).

У меня есть столбец со смесью типичного и нулевого символов. Я пытаюсь заменить нулевой символ другим значением. Я бы подумал, что следующее будет работать, но это не удачно:

select REPLACE(field_with_nullchar, char(0), ',') from FOO where BAR = 20

Ответы [ 6 ]

16 голосов
/ 13 мая 2010

В ответе Cade Roux есть два различных поведения: замена успешна (при использовании сортировки SQL) и неуспешна (используется сортировка Windows). Причина в используемом типе сопоставления.

Такое поведение было отправлено в Microsoft почти 4 года назад:

Q: При попытке заменить NUL-символ с replace (), это работает значение имеет сортировку SQL, но не Windows сортировка.

A: Это связано с тем, что 0x0000 является неопределенным символом в Windows Параметры сортировки. Все неопределенные символы игнорируются при сравнении, сортировке, и сопоставление с образцом. Так что жду 'a' + char (0) действительно ищет "A", и поиск символа (0) эквивалент пустой строки.

Способ обработки неопределенного символа немного сбивает с толку, но это способ, которым Windows определила их сортировку, и SQL Server соответствует общий Windows API.

В сопоставлении SQL понятия нет неопределенного персонажа. Каждый код баллу присваивается вес, поэтому мы не видим там проблемы.

но, к сожалению, до сих пор нет документов.

Таким образом, кажется, что единственное решение состоит в том, чтобы изменить параметры сортировки на параметры сортировки SQL (например, можно также использовать SQL_Latin1_General_CP1_CI_AS).

* Я удалил свой предыдущий ответ за ненадобностью

9 голосов
/ 13 мая 2010

Похоже, терминатор в стиле C также является терминатором в SQL:

SELECT  REPLACE(bad, CHAR(0), ' ')
FROM    (
         SELECT 'a' + CHAR(0) + 'b' AS bad
        ) AS X

Похоже, это также зависит от COLLATION:

SELECT  REPLACE(CAST(bad COLLATE SQL_Latin1_General_CP1_CI_AS AS varchar(10)), CHAR(0), ' ')
FROM    (
         SELECT 'a' + CHAR(0) + 'b' AS bad
        ) AS X

работает как ожидалось, по сравнению с:

SELECT  REPLACE(CAST(bad COLLATE Latin1_General_CI_AS AS varchar(10)), CHAR(0), ' ')
FROM    (
         SELECT 'a' + CHAR(0) + 'b' AS bad
        ) AS X
2 голосов
/ 14 мая 2010

A VARBINARY приведение должно работать с любым сопоставлением

SELECT 
   REPLACE(CAST(CAST(fld AS VARCHAR(5)) AS VARBINARY(5)), 0x0, ',')
FROM 
   (SELECT 'QQ' + CHAR(0) + 'WW' COLLATE Latin1_General_CI_AS AS fld) AS T

SELECT 
   REPLACE(CAST(CAST(fld AS VARCHAR(5)) AS VARBINARY(5)), 0x0, ',')
FROM 
   (SELECT 'QQ' + CHAR(0) + 'WW' COLLATE SQL_Latin1_General_CP1_CI_AS AS fld) AS T 

>>QQ,WW
>>QQ,WW
0 голосов
/ 10 сентября 2014

У меня была та же проблема, и использование nullif решило ее для меня.

Select nullif(field_with_nullchar,'') from FOO where BAR = 20
0 голосов
/ 13 мая 2010

Я только что провел тест на моем сервере (2008), и он прошел успешно. Это может быть связано с настройкой ANSI. Я попытаюсь просмотреть некоторые настройки здесь и посмотреть, смогу ли я воспроизвести вашу проблему.

DECLARE @test_null_char VARCHAR(20)

SET @test_null_char = 'aaa' + CHAR(0) + 'bbb'

SELECT @test_null_char    -- Returns "aaa bbb"

SET @test_null_char = REPLACE(@test_null_char, CHAR(0), 'ccc')

SELECT @test_null_char    -- Returns "aaacccbbb"
0 голосов
/ 13 мая 2010

Вы уверены, что это нулевые символы? Как ты их туда попал?

Похоже, что SQL Server рассматривает их как терминаторы строки. Этот запрос:

select 'aaa' + char(0) + 'bbb'

Возвращает aaa для меня (в SQL Server 2008).

Редактировать: Выше не так - это просто таблица результатов, которая обрабатывает их таким образом. Они отображаются в текстовом режиме.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...