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

414

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

Очевидное

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

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

Питер
источник

Ответы:

843

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

SELECT REPLACE(REPLACE(@str, CHAR(13), ''), CHAR(10), '')
RBarryYoung
источник
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
источник
Прошлые пользователи, обратите внимание на изменение и отказ от ответственности - и я прошу прощения за первоначальные предположения об использовании и цели.
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')
Cerebrus
источник
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, но если вы хотите заполнитель, такой как
или что-то, то первый подход немного более точен.

porkandcheese
источник
6

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

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

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

SELECT REPLACE(REPLACE(cast(@str as nvarchar(max)), CHAR(13), ''), CHAR(10), '')
AKD
источник
Хорошо, это выглядит великолепно. Теперь, что если я пытаюсь заменить это "! 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, я сократил их.

Davex
источник
1

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

Рохан
источник
1

Для решения @Cerebrus: для H2 для строк "+" не поддерживается. Так:

REPLACE(string, CHAR(13) || CHAR(10), 'replacementString')
Григорий Кислин
источник
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.

Майк
источник