Что Нулевой символ является литеральным в TSQL?

Я задаюсь вопросом, что литерал для Нулевого символа (например, '\0') находится в TSQL.

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

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

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

20
задан Alex 14 May 2010 в 09:18
поделиться

5 ответов

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

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

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

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

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

0
ответ дан 30 November 2019 в 00:39
поделиться

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

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

В: При попытке заменить символ NUL на replace () это работает: { Значение {1}} имеет сопоставление SQL, но не сопоставление Windows .

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

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

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

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

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

* Я удалил свой предыдущий ответ как ненужный

17
ответ дан 30 November 2019 в 00:39
поделиться

Похоже, что терминатор в стиле 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
10
ответ дан 30 November 2019 в 00:39
поделиться

A VARBINARY cast должен работать с любой collation

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
2
ответ дан 30 November 2019 в 00:39
поделиться

Я только что провел тест ниже на своем сервере (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
ответ дан 30 November 2019 в 00:39
поделиться