518

I would like to replace (or remove) a newline character in a TSQL string. Any ideas?

The obvious

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

just won't do it...

0

15 Answers 15

1023

Actually a new line in a SQL command or script string can be any of CR, LF or CR+LF. To get them all, you need something like this:

SELECT REPLACE(REPLACE(@str, CHAR(13), ''), CHAR(10), '')
7
  • 5
    @NielsBrinch That will work fine as long as that's the only type of line break in your strings. But SQL Server does support all three types. In fact, if you've ever extracted all of the system stored procedures and scripted views, you can find instances of all three as used by Microsoft themselves. Commented Mar 14, 2013 at 18:22
  • This worked for me b/c before I made this change copy and pasting the column data would have the cursor at the end of the text with two spaces. Ater making this change copying and pasting into notepad had the cursor sitting directly at the end of the text. It was causing an issue for me b/c in our front end GUI the new line char was showing up.
    – natur3
    Commented Mar 6, 2015 at 15:30
  • 10
    If the column data type is text then you need to cast to nvarchar first then replace SELECT REPLACE(REPLACE(cast(@str as nvarchar(max)), CHAR(13), ''), CHAR(10), '')
    – akd
    Commented Mar 23, 2016 at 10:33
  • 1
    @Slint Yes, good point. Practically speaking, to use this from client code you should add a column name. Though it is true that a lot of times you can get away with using .columns[0] instead. Commented May 27, 2016 at 12:28
  • 3
    For the version of Oracle I'm using, the statement is CHR, not CHAR. Just in case someone is trying to debug from Oracle. Otherwise, everything else applies.
    – Sedona
    Commented Mar 7, 2018 at 0:22
164
REPLACE(@string, CHAR(13) + CHAR(10), '')
3
  • 2
    This was the method I tried first, but it did not work reliably for all data. @RBarryYoung has it right above. Commented Mar 9, 2017 at 17:46
  • 1
    thanks, i had to modify this a little bit to work for me, in my case its: replace(REPLACE(@string, CHAR(13) , ''),CHAR(10), '')
    – user734028
    Commented Apr 24, 2018 at 5:06
  • 2
    Btw, use NCHAR(13) + NCHAR(10) when working with nvarchar/nchar strings to avoid potentially expensive implicit conversions between n and non-n string types.
    – Dai
    Commented Sep 8, 2022 at 6:49
53

I may be a year late to the party, but I work on queries & MS-SQL every day, and I got tired of the built-in functions LTRIM() & RTRIM() (and always having to call them together), and of not catching 'dirty' data that had newlines at the end, so I decided it was high time to implement a better TRIM function. I'd welcome peer feedback!

Disclaimer: this actually removes (replaces with a single whitespace) extended forms of whitespace (tab, line-feed, carriage-return, etc.), so it's been renamed as "CleanAndTrim" from my original answer. The idea here is that your string doesn't need such extra special-whitespace characters inside it, and so if they don't occur at the head/tail, they should be replaced with a plain space. If you purposefully stored such characters in your string (say, your column of data that you're about to run this on), DON'T DO IT! Improve this function or write your own that literally just removes those characters from the endpoints of the string, not from the 'body'.

Okay, now that the disclaimer is updated, here's the code.

-- =============================================
-- 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

Cheers!

Another Disclaimer: Your typical Windows line-break is CR+LF, so if your string contains those, you'd end up replacing them with "double" spaces.

UPDATE, 2016: A new version that gives you the option to replace those special-whitespace characters with other characters of your choice! This also includes commentary and the work-around for the Windows CR+LF pairing, i.e. replaces that specific char-pair with a single substitution.

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
4
  • Past users, please note the change and disclaimer -- and I apologize for the initial assumptions about usage & purpose.
    – NateJ
    Commented Mar 23, 2015 at 23:34
  • 1
    New update! Test-cases can be found here: sqlfiddle.com/#!6/585a2/1/0 -- SQLFiddle seemed to choke on my actual run of the test-cases so instead, I built a "test-case query builder" table & give you the 9 statements to copy-paste into your own SSMS window to run (after creating the schema of course, i.e. the function & the TestStrings table).
    – NateJ
    Commented May 12, 2016 at 19:12
  • 3
    Microsoft liked your TRIM function so much they included it in SQL Server 2017 ;) Commented Nov 26, 2020 at 14:21
  • No, you are not late :), thank you for the super SQL function. I had a tab along with a new line and this worked
    – Dobin
    Commented Apr 22, 2021 at 9:15
36

The Newline in T-SQL is represented by CHAR(13) & CHAR(10) (Carriage return + Line Feed). Accordingly, you can create a REPLACE statement with the text you want to replace the newline with.

REPLACE(MyField, CHAR(13) + CHAR(10), 'something else')
1
  • 12
    this isn't quite the same as the accepted answer; the accepted answer removes any combination of {13, 10}. this only removes the specific combination of 13 then 10. It doesn't make a diff for windows line endings, but other encoding will be missed here. Commented Jan 15, 2015 at 2:12
32

To do what most people would want, create a placeholder that isn't an actual line breaking character. Then you can actually combine the approaches for:

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

This way you replace only once. The approach of:

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

Works great if you just want to get rid of the CRLF characters, but if you want a placeholder, such as

<br/>

or something, then the first approach is a little more accurate.

1
  • What I did was instead of '' I replaced the linebreaks with a space. Which is fine if you have CR or LF you will just get one space, but if you have a CRLF then you get two. So I wrapped another replace around it all to replace double spaces with a single space: REPLACE(REPLACE(REPLACE(ClientName, CHAR(13), ' '), CHAR(10), ' '),' ',' ') Commented Nov 26, 2020 at 14:22
8

In SQL Server 2017 & later, use Trim

Select Trim(char(10) + char(13) from @str)
  1. it trims on starting and ending, not in the middle
  2. the order of \r and \n does not matter

I use it to trim special characters for a file name

Select Trim(char(10) + char(13) + ' *<>' from @fileName)
6

If your column data type is 'text' then you will get an error message as

Msg 8116, Level 16, State 1, Line 2 Argument data type text is invalid for argument 1 of replace function.

In this case you need to cast the text as nvarchar and then replace

SELECT REPLACE(REPLACE(cast(@str as nvarchar(max)), CHAR(13), ''), CHAR(10), '')
1
  • Ok, this looks great. Now, what if what I am trying to replace is "!crlf " and yes that is a space character after the !crlf. The concern is this occurs in the middle of the string, could I get away with: SELECT REPLACE(REPLACE(cast(@str as nvarchar(MAX)), CHAR(33), CHAR(13), CHAR(10), CHAR(32), '') or do I have this written incorrectly? The string looks like this: allow remote attackers to bypass a sandbox protection mechanism and gain privileges via a crafted web site t! hat is accessed with Internet Explorer, Focus on the word t! hat...that is my trouble spot.
    – bbcompent1
    Commented Sep 28, 2016 at 19:25
6

Sometimes

REPLACE(myString, CHAR(13) + CHAR(10), ' ')

won't work. In that case use the following snippet code:

REPLACE(REPLACE(myString, CHAR(13),''), CHAR(10), ' ')
6

I was wanting to sanitize the contents of a column to generate a csv file, so want to get rid of the comma (,) within the varchar as well as newline and carrage-return.

I also wanted to eventually use the generated csv to create another script (to insert rows into another db) so also needed to change ' within the varchar to '' so ended up with this...

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

There may be other nicer ways but it got the job done.

3

If you have an issue where you only want to remove trailing characters, you can try this:

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

This solved a problem I had with addresses where a procedure created a field with a fixed number of lines, even if those lines were empty. To save space in my SSRS report, I cut them down.

1

If you have have open procedure with using sp_helptext then just copy all text in new sql query and press ctrl+h button use regular expression to replace and put ^\n in find field replace with blank . for more detail check image.enter image description here

1

To @Cerebrus solution: for H2 for strings "+" is not supported. So:

REPLACE(string, CHAR(13) || CHAR(10), 'replacementString')
0

The answer posted above/earlier that was reported to replace CHAR(13)CHAR(10) carriage return:

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

Will never get to the REPLACE(MyField, CHAR(13) + CHAR(10), 'something else') portion of the code and will return the unwanted result of:

'something else''something else'

And NOT the desired result of a single:

'something else'

That would require the REPLACE script to be rewritten as such:

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

As the flow first tests the 1st/Furthest Left REPLACE statement, then upon failure will continue to test the next REPLACE statement.

0

A slightly less technical answer but rooted in the same issue. If anyone is outputting reports to txt files and wondering why their outputs are breaking into new lines even though your query specifically has replacements on new lines and you ae removing every char10 char 9 char13 you can find but the txt output still rolling into new lines. Do yourself a favor and just check the editor youre opening the text file with isn't wrapping newlines due to the length of the record being >1024 characters in length. If you output the same result to csv for example you can confirm if a line break is actually happening by seeing if the line break is still present or not. if not present then likely the issue is the notepad line length limiter which was my issue. issue disappeared once I moved to CSV output. If you need it to stay in txt then maybe consider cutting down the length of your query on certain fields

0

I don't think anyone covered this sligtly counter intuitive way

REPLACE(MyField, '
', '')

Where you just pres return inside constant.

Not the answer you're looking for? Browse other questions tagged or ask your own question.