2010-05-13 3 views
16

Мне интересно, что буквальный для Null character (например, '\ 0') находится в TSQL.Что такое литерал нулевого символа в TSQL?

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

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

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

Нулевой символ? Просьба привести пример, потому что все значение столбца будет null-use COALESCE. –

+1

OP ссылается на нулевой символ C-стиля (десятичный 0), который используется для завершения строк C-стиля. –

+3

Похоже, что он каким-то образом получил (n) столбцы varchar со встроенными нулевыми терминаторами, и он хочет их заменить, чтобы значение строки не обрезалось там, когда он его извлекал. – GalacticCowboy

ответ

15

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

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

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

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

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

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

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

Итак, единственное решение - изменить сортировку на SQL-сортировку (например, SQL_Latin1_General_CP1_CI_AS).

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

+5

Точно. Он имеет встроенные ограничители строк (NULL в смысле C, а не SQL) и хочет их исправить. – GalacticCowboy

9

Похоже терминатор 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 
0

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

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

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

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

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

+3

Вы просматривали результаты в текстовом режиме? Когда я запускаю его в режиме сетки, он отображается как «aaa», но в текстовом режиме для набора результатов он отображает «aaa bbb» –

+0

@Tom - о, вы правы. Приветствия. – Blorgbeard

0

Я только что проверил тест ниже на своем сервере (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

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

У меня была такая же проблема и с помощью nullif решить это для меня.

Select nullif(field_with_nullchar,'') from FOO where BAR = 20 
Смежные вопросы