Замініть новий рядок у TSQL


414

Я хотів би замінити (або видалити) символ нового рядка в TSQL-рядку. Будь-які ідеї?

Очевидне

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

просто не зроблять цього ...

Відповіді:


841

Фактично, новий рядок у команді або рядку сценарію може бути будь-яким із CR, LF або CR + LF. Щоб отримати їх все, вам потрібно щось подібне:

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

5
@NielsBrinch Це буде добре, поки це єдиний тип розриву рядків у ваших рядках. Але SQL Server підтримує всі три типи. Насправді, якщо ви коли-небудь витягували всі збережені в системі процедури та сценарії представлень, ви можете знайти екземпляри всіх трьох, якими користуються самі Microsoft.
RBarryYoung

Це працювало для мене з / п до того, як я зробив цю зміну копію і вставку даних стовпця матиме курсор у кінці тексту з двома пробілами. Після внесення цієї зміни копіювання та вставки в блокнот курсор сидів прямо в кінці тексту. Це викликало проблему для мене в / ч у нашому інтерфейсі GUI, що з'явилася нова лінійка.
natur3

8
Якщо тип даних стовпця є текстовим, то спочатку вам потрібно передати nvarchar, а потім замінити SELECT REPLACE (ЗАМЕНИТИ (cast (@str як nvarchar (max)), CHAR (13), ''), CHAR (10), '')
акд

1
@Slint Так, хороший момент. Практично кажучи, щоб використовувати це з коду клієнта, вам слід додати назву стовпця. Хоча це правда, що багато разів ви можете піти з використання .columns[0]замість цього.
RBarryYoung

2
Для версії Oracle, яку я використовую, заява - CHR, а не CHAR. Про всяк випадок, якщо хтось намагається налагодити з Oracle. Інакше стосується всього іншого.
Седона

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

2
Це був метод, який я спробував спочатку, але він не працював надійно для всіх даних. @RBarryYoung має право вище.
Марк W Діксон

1
дякую, мені довелося трохи змінити це, щоб він працював на мене, в моєму випадку його: Замінити (ЗАМЕНИТИ (@string, CHAR (13), ''), CHAR (10), '')
користувач734028

36

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

Відмова від відповідальності : це фактично вилучає (замінює єдиний пробіл) розширені форми пробілів (вкладка, подача рядків, повернення каретки тощо), тому з моєї оригінальної відповіді вона була перейменована як "CleanAndTrim". Ідея тут полягає в тому, що ваша струна не потрібна такі зайві символи-пробіли всередині неї, і тому, якщо вони не зустрічаються біля голови / хвоста, їх слід замінити звичайним пробілом. Якщо ви цілеспрямовано зберігаєте такі символи у рядку (скажімо, стовпець даних, над яким ви збираєтеся це запустити), НЕ робіть цього! Удосконаліть цю функцію або напишіть своє, що буквально просто видаляє ці символи з кінцевих точок рядка, а не з 'body'.

Добре, тепер, коли відмова від відповідальності оновлена, ось код.

-- =============================================
-- 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, здавалося, задихнувся від мого фактичного запуску тестових випадків, тому замість цього я створив таблицю " конструктор запитів тестових випадків" & дайте вам 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. Стурбованість полягає в тому, що це відбувається в середині рядка, чи можу я піти з: ВИБІР ЗАМІНУ (ЗАМІНА (заголовок (@str як nvarchar (MAX)), CHAR (33), CHAR (13), CHAR (10), CHAR (32), '') чи це я написав неправильно? Рядок виглядає приблизно так: дозвольте віддаленим зловмисникам обходити механізм захисту пісочниці та отримувати привілеї через створений веб-сайт. слово т! капелюх ... це моя біда.
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')

Оскільки потік спочатку тестує оператор 1st / Furthest Left REPLACE, то після відмови буде продовжено тестування наступного оператора REPLACE.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.