Заменить новую строку в TSQL


414

Я хотел бы заменить (или удалить) символ новой строки в строке TSQL. Любые идеи?

Очевидное

REPLACE(@string, CHAR(13), '')

просто не буду этого делать ...

Ответы:


843

Фактически, новая строка в строке команды SQL или скрипта может быть любой из CR, LF или CR + LF. Чтобы получить их все, вам нужно что-то вроде этого:

SELECT REPLACE(REPLACE(@str, CHAR(13), ''), CHAR(10), '')

5
@NielsBrinch Это будет хорошо работать до тех пор, пока это единственный тип разрыва строки в ваших строках. Но SQL Server поддерживает все три типа. На самом деле, если вы когда-либо извлекали все системные хранимые процедуры и сценарии, вы можете найти экземпляры всех трех, которые используются самими Microsoft.
— RBarryYoung

Это работало для меня до того, как я сделал эту копию изменений, и при вставке данных столбца курсор в конце текста имел бы два пробела. После внесения этого изменения при копировании и вставке в блокнот курсор находился прямо в конце текста. Это вызывало проблему для меня, потому что в нашем интерфейсном интерфейсе появился новый линейный символ.
— natur3

8
Если тип данных столбца является текстовым, вам необходимо сначала привести к nvarchar, а затем заменить SELECT REPLACE (REPLACE (cast (@str как nvarchar (max)), CHAR (13), ''), CHAR (10), '')
— АКД

1
@ Слинт Да, хорошая мысль. Практически говоря, чтобы использовать это из клиентского кода, вы должны добавить имя столбца. Хотя это правда, что много раз вы можете избежать использования .columns[0]вместо этого.
— RBarryYoung

2
Для версии Oracle, которую я использую, оператором является CHR, а не CHAR. На всякий случай кто-то пытается отладить у Oracle. В остальном все остальное применимо.
— Седона

143
REPLACE(@string, CHAR(13) + CHAR(10), '')

2
Это был метод, который я попробовал первым, но он не работал надежно для всех данных. @RBarryYoung имеет это прямо выше.
— Марк Диксон

1
спасибо, мне пришлось немного изменить это, чтобы работать для меня, в моем случае это: replace (REPLACE (@string, CHAR (13), ''), CHAR (10), '')
— user734028

36

Я могу на год опоздать на вечеринку, но я работаю над запросами и MS-SQL каждый день, и мне надоели встроенные функции LTRIM () и RTRIM () (и всегда приходится их вызывать вместе), и не отловить «грязные» данные, в конце которых были символы новой строки, поэтому я решил, что пришло время реализовать лучшую функцию TRIM. Я бы приветствовал отзывы коллег!

Отказ от ответственности : это фактически удаляет (заменяет одним пробелом) расширенные формы пробелов (табуляция, перевод строки, возврат каретки и т. Д.), Поэтому он был переименован в «CleanAndTrim» из моего первоначального ответа. Идея здесь в том, что вашей строке не нужны такие дополнительные специальные пробельные символы внутри нее, и поэтому, если они не встречаются в голове / хвосте, их следует заменить обычным пробелом. Если вы целенаправленно сохранили такие символы в вашей строке (скажем, в столбце данных, на котором вы собираетесь это выполнить), НЕ ДЕЛАЙТЕ ЭТОГО! Усовершенствуйте эту функцию или напишите свою собственную, которая буквально удаляет эти символы из конечных точек строки, а не из «тела».

Хорошо, теперь, когда отказ от ответственности обновлен, вот код.

-- =============================================
-- Description: TRIMs a string 'for real' - removes standard whitespace from ends,
-- and replaces ASCII-char's 9-13, which are tab, line-feed, vert tab,
-- form-feed, & carriage-return (respectively), with a whitespace
-- (and then trims that off if it's still at the beginning or end, of course).
-- =============================================
CREATE FUNCTION [fn_CleanAndTrim] (
       @Str nvarchar(max)
)
RETURNS nvarchar(max) AS
BEGIN
       DECLARE @Result nvarchar(max)

       SET @Result = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
              LTRIM(RTRIM(@Str)), CHAR(9), ' '), CHAR(10), ' '), CHAR(11), ' '), CHAR(12), ' '), CHAR(13), ' ')))

       RETURN @Result
END

Ура!

Еще один отказ от ответственности : ваш типичный разрыв строки в Windows - CR + LF, поэтому, если ваша строка содержит их, вы в конечном итоге замените их на «двойные» пробелы.

ОБНОВЛЕНИЕ, 2016 : Новая версия, которая дает вам возможность заменить эти специальные пробельные символы другими персонажами на ваш выбор! Это также включает в себя комментарии и обходной путь для пары Windows CR + LF, то есть заменяет эту конкретную пару символов одной заменой.

IF OBJECT_ID('dbo.fn_CleanAndTrim') IS NULL
    EXEC ('CREATE FUNCTION dbo.fn_CleanAndTrim () RETURNS INT AS BEGIN RETURN 0 END')
GO
-- =============================================
-- Author: Nate Johnson
-- Source: http://stackoverflow.com/posts/24068265
-- Description: TRIMs a string 'for real' - removes standard whitespace from ends,
-- and replaces ASCII-char's 9-13, which are tab, line-feed, vert tab, form-feed,
-- & carriage-return (respectively), with a whitespace or specified character(s).
-- Option "@PurgeReplaceCharsAtEnds" determines whether or not to remove extra head/tail
-- replacement-chars from the string after doing the initial replacements.
-- This is only truly useful if you're replacing the special-chars with something
-- **OTHER** than a space, because plain LTRIM/RTRIM will have already removed those.
-- =============================================
ALTER FUNCTION dbo.[fn_CleanAndTrim] (
    @Str NVARCHAR(MAX)
    , @ReplaceTabWith NVARCHAR(5) = ' '
    , @ReplaceNewlineWith NVARCHAR(5) = ' '
    , @PurgeReplaceCharsAtEnds BIT = 1
)
RETURNS NVARCHAR(MAX) AS
BEGIN
    DECLARE @Result NVARCHAR(MAX)

    --The main work (trim & initial replacements)
    SET @Result = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
        LTRIM(RTRIM(@Str))  --Basic trim
        , NCHAR(9), @ReplaceTabWith), NCHAR(11), @ReplaceTabWith)   --Replace tab & vertical-tab
        , (NCHAR(13) + NCHAR(10)), @ReplaceNewlineWith) --Replace "Windows" linebreak (CR+LF)
        , NCHAR(10), @ReplaceNewlineWith), NCHAR(12), @ReplaceNewlineWith), NCHAR(13), @ReplaceNewlineWith)))   --Replace other newlines

    --If asked to trim replacement-char's from the ends & they're not both whitespaces
    IF (@PurgeReplaceCharsAtEnds = 1 AND NOT (@ReplaceTabWith = N' ' AND @ReplaceNewlineWith = N' '))
    BEGIN
        --Purge from head of string (beginning)
        WHILE (LEFT(@Result, DATALENGTH(@ReplaceTabWith)/2) = @ReplaceTabWith)
            SET @Result = SUBSTRING(@Result, DATALENGTH(@ReplaceTabWith)/2 + 1, DATALENGTH(@Result)/2)

        WHILE (LEFT(@Result, DATALENGTH(@ReplaceNewlineWith)/2) = @ReplaceNewlineWith)
            SET @Result = SUBSTRING(@Result, DATALENGTH(@ReplaceNewlineWith)/2 + 1, DATALENGTH(@Result)/2)

        --Purge from tail of string (end)
        WHILE (RIGHT(@Result, DATALENGTH(@ReplaceTabWith)/2) = @ReplaceTabWith)
            SET @Result = SUBSTRING(@Result, 1, DATALENGTH(@Result)/2 - DATALENGTH(@ReplaceTabWith)/2)

        WHILE (RIGHT(@Result, DATALENGTH(@ReplaceNewlineWith)/2) = @ReplaceNewlineWith)
            SET @Result = SUBSTRING(@Result, 1, DATALENGTH(@Result)/2 - DATALENGTH(@ReplaceNewlineWith)/2)
    END

    RETURN @Result
END
GO

Прошлые пользователи, обратите внимание на изменение и отказ от ответственности - и я прошу прощения за первоначальные предположения об использовании и цели.
— NateJ

1
Новое обновление! Тестовые случаи можно найти здесь: sqlfiddle.com/#!6/585a2/1/0 - SQLFiddle, похоже, душил мой фактический запуск тестовых случаев, поэтому вместо этого я создал таблицу «построитель запросов test-case» и дать вам 9 операторов для копирования-вставки в собственное окно SSMS для запуска (после создания схемы, конечно, то есть функции и таблицы TestStrings).
— NateJ

32

Новая строка в T-SQL представлена ​​символами CHAR (13) и CHAR (10) (возврат каретки + перевод строки). Соответственно, вы можете создать инструкцию REPLACE с текстом, которым вы хотите заменить символ новой строки.

REPLACE(MyField, CHAR(13) + CHAR(10), 'something else')

9
это не совсем то же самое, что принятый ответ; принятый ответ удаляет любую комбинацию {13, 10}. это только удаляет конкретную комбинацию из 13, а затем 10. Она не делает различий для концов строк Windows, но здесь будет пропущена другая кодировка.
— Эндрю Хилл

24

Чтобы сделать то, что хотели бы большинство людей, создайте заполнитель, который не является действительным символом разрыва строки. Тогда вы действительно можете объединить подходы для:

REPLACE(REPLACE(REPLACE(MyField, CHAR(13) + CHAR(10), 'something else'), CHAR(13), 'something else'), CHAR(10), 'something else')

Таким образом, вы заменяете только один раз. Подход:

REPLACE(REPLACE(MyField, CHAR(13), ''), CHAR(10), '')

Прекрасно работает, если вы просто хотите избавиться от символов CRLF, но если вы хотите заполнитель, такой как
или что-то, то первый подход немного более точен.


6

Если тип данных столбца - « текст », вы получите сообщение об ошибке в виде

Сообщение 8116, уровень 16, состояние 1, строка 2 Текст типа данных аргумента недопустим для аргумента 1 функции замены.

В этом случае вам нужно привести текст к nvarchar, а затем заменить

SELECT REPLACE(REPLACE(cast(@str as nvarchar(max)), CHAR(13), ''), CHAR(10), '')

Хорошо, это выглядит великолепно. Теперь, что если я пытаюсь заменить это "! Crlf", и да, это символ пробела после! Crlf. Проблема заключается в том, что это происходит в середине строки, можно ли мне обойтись без: SELECT REPLACE (REPLACE (cast (@str as nvarchar (MAX)), CHAR (33), CHAR (13), CHAR (10), CHAR (32), '') или я написал это неправильно? Строка выглядит следующим образом: позволяют удаленным злоумышленникам обойти механизм защиты песочницы и получить привилегии через специально созданный веб-сайт, доступ к которому осуществляется через Internet Explorer, сосредоточиться на слово t! hat ... это мое проблемное место.
— bbcompent1

3

Если у вас есть проблема, из-за которой вы хотите удалить только завершающие символы, вы можете попробовать это:

WHILE EXISTS
(SELECT * FROM @ReportSet WHERE
    ASCII(right(addr_3,1)) = 10
    OR ASCII(right(addr_3,1)) = 13
    OR ASCII(right(addr_3,1)) = 32)
BEGIN
    UPDATE @ReportSet
    SET addr_3 = LEFT(addr_3,LEN(addr_3)-1)
    WHERE 
    ASCII(right(addr_3,1)) = 10
    OR ASCII(right(addr_3,1)) = 13
    OR ASCII(right(addr_3,1)) = 32
END

Это решило проблему с адресами, где процедура создала поле с фиксированным числом строк, даже если эти строки были пустыми. Чтобы сэкономить место в моем отчете SSRS, я сократил их.


1

Если у вас есть открытая процедура с использованием sp_helptext, просто скопируйте весь текст в новый SQL-запрос и нажмите кнопку ctrl + h, используйте регулярное выражение для замены и поместите ^ \ n в поле поиска заменить пустым. для более подробной информации проверьте изображение. введите описание изображения здесь



0

Ответ, опубликованный выше / ранее, который, как сообщалось, заменит CHAR (13) CHAR (10) возврат каретки:

REPLACE(REPLACE(REPLACE(MyField, CHAR(13) + CHAR(10), 'something else'), CHAR(13), 'something else'), CHAR(10), 'something else')

Никогда не попадет в REPLACE(MyField, CHAR(13) + CHAR(10), 'something else')часть кода и вернет нежелательный результат:

'something else''something else'

И НЕ желаемый результат одного:

'something else'

Для этого потребуется переписать скрипт REPLACE следующим образом:

REPLACE(REPLACE(REPLACE(MyField, CHAR(10), 'something else'), CHAR(13), 'something else'), CHAR(13) + CHAR(10), 'something else')

Поскольку поток сначала проверяет 1-й / крайний левый оператор REPLACE, затем при неудаче продолжит тестировать следующий оператор REPLACE.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.