แทนที่บรรทัดใหม่ใน TSQL


414

ฉันต้องการแทนที่ (หรือลบ) อักขระบรรทัดใหม่ในสตริง TSQL ความคิดใด ๆ

อย่างชัดเจน

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

แค่จะไม่ทำมัน ...

คำตอบ:


841

จริงๆแล้วบรรทัดใหม่ในคำสั่ง SQL หรือสตริงสคริปต์สามารถเป็น CR, LF หรือ CR + LF ในการรับทั้งหมดคุณต้องมีสิ่งนี้:

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

5
@NielsBrinch ที่จะทำงานได้ดีตราบใดที่เป็นตัวแบ่งบรรทัดประเภทเดียวในสตริงของคุณ แต่ SQL Server รองรับทั้งสามประเภท ในความเป็นจริงถ้าคุณเคยแยกโพรซีเดอร์ที่เก็บไว้ทั้งหมดและมุมมองแบบสคริปต์คุณสามารถค้นหาอินสแตนซ์ของทั้งสามตามที่ Microsoft ใช้เอง
RBarryYoung

สิ่งนี้ใช้ได้สำหรับฉัน b / c ก่อนที่ฉันจะทำการคัดลอกการเปลี่ยนแปลงและวางข้อมูลคอลัมน์จะมีเคอร์เซอร์ที่ท้ายข้อความที่มีช่องว่างสองช่อง หลังการเปลี่ยนแปลงนี้การคัดลอกและวางลงในแผ่นจดบันทึกทำให้เคอร์เซอร์นั่งตรงส่วนท้ายของข้อความ มันทำให้เกิดปัญหาสำหรับฉัน b / c ในหน้า GUI ของเราที่ char บรรทัดใหม่กำลังแสดงขึ้น
natur3

8
หากชนิดข้อมูลคอลัมน์เป็นข้อความคุณต้องส่งไปยัง nvarchar ก่อนจากนั้นแทนที่ SELECT REPLACE (REPLACE (cast (@str เป็น nvarchar (สูงสุด)), CHAR (13), ''), CHAR (10), '')
AKD

1
@Slint ใช่จุดดี พูดจริงเพื่อใช้จากรหัสลูกค้าคุณควรเพิ่มชื่อคอลัมน์ แม้ว่ามันจะเป็นความจริงที่หลายครั้งคุณสามารถใช้.columns[0]แทนได้
RBarryYoung

2
สำหรับเวอร์ชันของ Oracle ที่ฉันใช้คำสั่งนี้คือ CHR ไม่ใช่ CHAR ในกรณีที่มีคนพยายามที่จะแก้ปัญหาจาก Oracle มิฉะนั้นทุกอย่างจะถูกนำมาใช้
เซดอนา

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

2
นี่เป็นวิธีที่ฉันลองก่อน แต่มันก็ไม่ได้ผลสำหรับข้อมูลทั้งหมด @RarryYoung มีสิทธิ์ด้านบน
Mark W Dickson

1
ขอบคุณฉันต้องแก้ไขเล็กน้อยเพื่อให้ฉันในกรณีของฉันมันแทนที่: (แทนที่ (@ string, CHAR (13), ''), CHAR (10), '')
user734028

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 ของคุณเองเพื่อเรียกใช้ (หลังจากสร้าง schema ของหลักสูตรเช่นฟังก์ชันและตาราง TestStrings)
NateJ

32

Newline ใน T-SQL แสดงด้วย CHAR (13) & CHAR (10) (Carriage return + Line Feed) ดังนั้นคุณสามารถสร้างคำสั่ง REPLACE ด้วยข้อความที่คุณต้องการแทนที่บรรทัดใหม่ด้วย

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

9
นี่ไม่ใช่คำตอบที่ยอมรับได้ คำตอบที่ยอมรับจะลบการรวมกันของ {13, 10} สิ่งนี้จะลบเฉพาะการรวมกันของ 13 แล้ว 10 มันไม่ได้ทำให้ diff สำหรับปลายสาย windows แต่การเข้ารหัสอื่น ๆ จะพลาดที่นี่
Andrew Hill

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), '') หรือฉันเขียนอย่างไม่ถูกต้องหรือไม่สตริงมีลักษณะดังนี้: อนุญาตให้ผู้โจมตีระยะไกลเลี่ยงผ่านกลไกการป้องกัน sandbox และได้รับสิทธิพิเศษผ่านทางเว็บไซต์หมวกที่สร้างขึ้นมาด้วย Internet Explorer มุ่งเน้นไปที่ word 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 ในฟิลด์ค้นหาแทนที่ด้วยช่องว่าง สำหรับภาพตรวจสอบรายละเอียดเพิ่มเติม ป้อนคำอธิบายรูปภาพที่นี่


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')

เมื่อโฟลว์แรกทดสอบคำสั่ง REPLACE ซ้าย / สุดสุดจากนั้นเมื่อความล้มเหลวจะดำเนินการทดสอบคำสั่ง REPLACE ต่อไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.