Заменить нулевой символ в строке в SQL - PullRequest
6 голосов
/ 19 февраля 2010

Мне нужно заменить нулевой символ в строке SQL, я не могу найти правильную команду для достижения этой цели.Я использовал replace (myString, '\ 0', ''), но, похоже, это не сработает, любая помощь будет полезна

Ответы [ 10 ]

10 голосов
/ 27 июня 2014

Трюк, который работает, состоит в том, чтобы СОБЫТЬ ваше значение в Latin1_General_BIN перед использованием REPLACE, а также использовать nchar (0x00) COLLATE Latin1_General_BIN для string_pattern .

REPLACE (string_expression, string_pattern , string_replacement)

 select 
 [Terminated]      =          N'123' + nchar(0) + N'567'                                
,[Replaced with -] = REPLACE((N'123' + nchar(0) + N'567') COLLATE Latin1_General_BIN
                                          , nchar(0x00) COLLATE Latin1_General_BIN 
                                                 ,'-')      
,[Removed]        = REPLACE((N'123' + nchar(0) + N'567') COLLATE Latin1_General_BIN
                                    , nchar(0x00)      COLLATE Latin1_General_BIN
                                            ,'')    

Вот результат (используйте Вывод в текст):

Contains   Replaced with -   Removed
---------- ----------------- --------
123 567    123-567           123567
10 голосов
/ 19 февраля 2010

Используйте это:

REPLACE(myString, char(0), '')
4 голосов
/ 03 марта 2010

Для латинских букв: выберите REPLACE ('Ho' + CHAR (0) + 'mer' COLLATE SQL_Latin1_General_CP1_CS_AS, CHAR (0), '')

Для русских символов: выберите REPLACE (('Го' + CHAR (0) + 'мер') COLLATE Cyrillic_General_BIN, CHAR (0), '')

2 голосов
/ 30 мая 2017

Эти функции удаляют нулевые символы из строк Unicode, по крайней мере, в SQL Server 2008.

-- Remove all null characters
CREATE FUNCTION RemoveNulls(@s nvarchar(max))
RETURNS nvarchar(max)
AS
BEGIN
    DECLARE @r nvarchar(max);
    SET @r = REPLACE(@s COLLATE Latin1_General_BIN, NCHAR(0), N'');
    RETURN @r; 
END
-- Remove all characters from the first null character
CREATE FUNCTION TrimNull(@s nvarchar(max))
RETURNS nvarchar(max)
AS
BEGIN
    DECLARE @r nvarchar(max);
    DECLARE @i int = CHARINDEX(NCHAR(0), @s COLLATE Latin1_General_BIN);
    IF @i = 0
        SET @r = @s;
    ELSE
        SET @r = SUBSTRING(@s, 1, @i - 1);
    RETURN @r; 
END
-- Example usage
DECLARE @s nvarchar(10) = N'Test' + NCHAR(0) + N'!';
SELECT dbo.RemoveNulls(@s), dbo.TrimNull(@s);
--> Test!, Test

В моем случае поля из ODBC были дополнены до 8000 символов нулем, а TrimNull был намного быстрее, чем RemoveNulls.

2 голосов
/ 30 марта 2013

Если у вас Только есть ASCII (Char / VarChar) строки, тогда это будет работать так, как @DyingCactus предлагает:

REPLACE(myString, Char(0x00), '')

Однако , если вы имеете дело с Null-Termination Strings и пытаетесь исправить или преобразовать что-то вроде XML, и ваши данные Unicode (nChar / nVarChar), то используйте это:

(CASE WHEN UNICODE(SUBSTRING(myString, LEN(myString), 1)) = 0x0000
      THEN SUBSTRING(myString, 1, LEN(myString) - 1)
      ELSE myString END)

Работает как для ASCII (Char / VarChar), так и для Unicode (nChar / nVarChar).

Примечание

Использование функции Replace () с Char (0) или nChar (0) будет НЕ работать для Unicode (nChar / nVarChar).Это ошибка в функции SQL Server Replace ().Вы можете разыграть как VarChar, затем использовать Replace (), но тогда вы потеряете любые специальные символы Unicode / Non-ASCII, которые вы, возможно, намеревались сохранить.В противном случае вы бы не использовали тип данных Unicode (который занимает вдвое больше места для хранения ваших данных).Если у вас есть нулевые символы, смешанные со строками Unicode (и не только в конце), и для целей вашего запроса поддержание символов Unicode неважно, то в качестве последнего средства вы можете использовать это:

(CASE WHEN myString LIKE (N'%' + nCHAR(0x0000) + N'%')--Has Null-Character(s).
      THEN REPLACE(CAST(myString as VarChar(MAX)), Char(0x00), '')--Cast as ASCII
      ELSE myString END)--Else, leave as Unicode to preserve Unicode-Only chars.
2 голосов
/ 19 февраля 2010

Я не совсем уверен, что не так с вашими строками, но вот несколько вещей, которые вы можете попробовать, вы используете varchar ?, отредактируйте вопрос с более подробной информацией:

, если в строке есть NULL-символы:

declare @x varchar(10)
set @x='123'+char(0)+'456'
SELECT @x AS Has_NULL_in_it, REPLACE(@x, char(0), '') AS Has_NULL_removed

ВЫХОД:

Has_NULL_in_it Has_NULL_removed
-------------- ----------------
123 456        123456

(1 row(s) affected)

Если вы не можете определить символ в строке, попробуйте этот ASCII:

DECLARE @y varchar(10),@c int
set @y='123'+char(0)+'456'
set @c=0
WHILE @c<LEN(@y)
BEGIN
    SET @c=@c+1
    PRINT CONVERT(varchar(5),@c)+' - '+SUBSTRING(@y,@c,1)+' - CHAR('+CONVERT(varchar(5),ASCII(SUBSTRING(@y,@c,1)))+')'
END

ВЫХОД:

1 - 1 - CHAR(49)
2 - 2 - CHAR(50)
3 - 3 - CHAR(51)
4 - - CHAR(0)
5 - 4 - CHAR(52)
6 - 5 - CHAR(53)
7 - 6 - CHAR(54)

попробуйте этот Unicode:

DECLARE @y nvarchar(10),@c int
set @y='123'+char(0)+'456'
set @c=0
WHILE @c<LEN(@y)
BEGIN
    SET @c=@c+1
    PRINT CONVERT(nvarchar(5),@c)+' - '+SUBSTRING(@y,@c,1)+' - UNICODE('+CONVERT(nvarchar(5),UNICODE(SUBSTRING(@y,@c,1)))+')'
END

, если у вас есть строки, которые полностью равны NULL:

declare @z varchar(10)
set @z=NULL
select @z AS IS_NULL, ISNULL(@Z,'') AS NULL_Removed

ВЫХОД:

IS_NULL    NULL_Removed
---------- ------------
NULL       

(1 row(s) affected)
1 голос
/ 19 февраля 2010

Если вы объединяете значения, чтобы получить строку, используйте IsNull (значение, замена) , чтобы избежать использования нулевых значений, или установите CONCAT_NULL_YIELDS_NULL ON, чтобы избежать появления в результате пустых строк.*

0 голосов
/ 10 августа 2018

выберите zz.xx , заменить (zz.xx, '& # x00;', '') от ( Выбрать t.string_with_null, ( выберите s.string_with_null + '' из TABLE_1 с где s.token_hash = t.token_hash для пути XML ('') ) хх из ТАБЛИЦЫ_1 т (нольлок) ) ZZ

0 голосов
/ 30 января 2017

У нас была та же проблема: завершающий символ \ 0 в полях nvarchar и неспособный заменить его любым из предложенных вариантов REPLACE (SQL Server 2008).При использовании

LEFT(Bar, LEN(Bar)-1)

он обрезает последний обычный символ вместе с \ 0!

. Наше решение теперь исправить поля - это (как бы странно это ни казалось на первый взгляд):

UPDATE Foo
    SET Bar = LEFT(Bar, LEN(Bar))
WHERE RIGHT(Bar, 1) = CHAR(0)
0 голосов
/ 02 апреля 2015

Примеры разрешены

CREATE FUNCTION dbo.F_ReplaceNullChar( @STR NVARCHAR(MAX) )
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @i INT=0
DECLARE @RET NVARCHAR(MAX)=''
    WHILE @I<LEN(@STR) 
    BEGIN 
        SET @i=@i+1
        IF UNICODE(SUBSTRING(@STR,@i,1)) <> 0x0000
            SET @RET=@RET+SUBSTRING(@STR,@i,1)

    END
    RETURN @RET
END
GO

SELECT LEN(mycol) lenbefore,mycol,
 LEN( dbo.F_ReplaceNullChar(mycol)) lenafter, dbo.F_ReplaceNullChar(mycol) mycolafter 
FROM mytab
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...