Ganti baris baru di TSQL

414

Saya ingin mengganti (atau menghapus) karakter baris baru dalam string TSQL. Ada Ide?

Yang jelas

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

tidak akan melakukannya ...

Peter
sumber

Jawaban:

843

Sebenarnya baris baru dalam perintah SQL atau string skrip dapat berupa CR, LF atau CR + LF. Untuk mendapatkan semuanya, Anda perlu sesuatu seperti ini:

SELECT REPLACE(REPLACE(@str, CHAR(13), ''), CHAR(10), '')
RBarryYoung
sumber
5
@NielsBrinch Itu akan bekerja dengan baik selama itu adalah satu-satunya jenis pemutusan jalur dalam string Anda. Tetapi SQL Server mendukung ketiga tipe tersebut. Bahkan, jika Anda pernah mengekstrak semua prosedur tersimpan sistem dan tampilan skrip, Anda dapat menemukan contoh ketiganya seperti yang digunakan oleh Microsoft sendiri.
RBarryYoung
Ini bekerja untuk saya b / c sebelum saya membuat salinan perubahan ini dan menempelkan data kolom akan memiliki kursor di akhir teks dengan dua spasi. Ater yang membuat perubahan ini menyalin dan menempel ke notepad memiliki kursor duduk langsung di akhir teks. Itu menyebabkan masalah bagi saya b / c di GUI front end kami baris baru char muncul.
natur3
8
Jika tipe data kolom adalah teks maka Anda harus melakukan cast ke nvarchar terlebih dahulu kemudian ganti SELECT REPLACE (REPLACE (cast (@str as nvarchar (max)), CHAR (13), ''), CHAR (10), '')
akd
1
@ Slint Ya, poin bagus. Secara praktis, untuk menggunakan ini dari kode klien Anda harus menambahkan nama kolom. Meskipun memang benar bahwa banyak kali Anda dapat menggunakannya .columns[0].
RBarryYoung
2
Untuk versi Oracle yang saya gunakan, pernyataannya adalah CHR, bukan CHAR. Untuk berjaga-jaga seandainya seseorang mencoba melakukan debug dari Oracle. Kalau tidak, semua yang lain berlaku.
Sedona
143
REPLACE(@string, CHAR(13) + CHAR(10), '')
Mitch Wheat
sumber
2
Ini adalah metode yang saya coba pertama kali, tetapi tidak dapat diandalkan untuk semua data. @RBarryYoung memilikinya tepat di atas.
Mark W Dickson
1
terima kasih, saya harus memodifikasi ini sedikit agar berfungsi untuk saya, dalam kasus saya ini: replace (REPLACE (@string, CHAR (13), ''), CHAR (10), '')
user734028
36

Saya mungkin terlambat satu tahun ke pesta, tapi saya mengerjakan pertanyaan & MS-SQL setiap hari, dan saya bosan dengan fungsi bawaan LTRIM () & RTRIM () (dan selalu harus memanggil mereka bersama-sama), dan tidak menangkap data 'kotor' yang memiliki baris baru di akhir, jadi saya memutuskan sudah saatnya menerapkan fungsi TRIM yang lebih baik. Saya akan menyambut umpan balik rekan!

Penafian : ini benar-benar menghapus (menggantikan dengan spasi tunggal) memperluas bentuk spasi putih (tab, umpan baris, carriage-return, dll.), Jadi ini telah diganti namanya menjadi "CleanAndTrim" dari jawaban asli saya. Idenya di sini adalah bahwa string Anda tidak memerlukan karakter spasi khusus ekstra di dalamnya, dan jadi jika mereka tidak muncul di kepala / ekor, mereka harus diganti dengan ruang kosong. Jika Anda sengaja menyimpan karakter tersebut di string (katakanlah, kolom data yang akan Anda jalankan), JANGAN MELAKUKANNYA! Perbaiki fungsi ini atau tulis karakter Anda sendiri yang benar-benar hanya menghilangkan karakter-karakter tersebut dari titik akhir string, bukan dari 'tubuh'.

Oke, sekarang setelah disclaimer diperbarui, ini kodenya.

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

Bersulang!

Penafian lain : Line-break Windows khas Anda adalah CR + LF, jadi jika string Anda berisi itu, Anda akhirnya akan menggantinya dengan spasi "ganda".

UPDATE, 2016 : Versi baru yang memberi Anda opsi untuk mengganti karakter spasi khusus dengankarakter lain pilihan Anda! Ini juga termasuk komentar dan penyelesaian untuk pasangan Windows CR + LF, yaitu menggantikan karakter pasangan tertentu dengan satu substitusi.

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
sumber
Pengguna lama, harap perhatikan perubahan dan penafian - dan saya minta maaf atas asumsi awal tentang penggunaan & tujuan.
NateJ
1
Pembaruan baru! Kasing -uji dapat ditemukan di sini: sqlfiddle.com/#!6/585a2/1/0 - SQLFiddle tampaknya tersedak pada jalankan yang sebenarnya dari kasing -kasing jadi, saya membangun tabel "pembuat huruf-kueri pembangun" & memberi Anda 9 pernyataan untuk menyalin-tempel ke jendela SSMS Anda sendiri untuk dijalankan (setelah membuat skema tentu saja, yaitu fungsi & tabel TestStrings).
NateJ
32

Newline di T-SQL diwakili oleh CHAR (13) & CHAR (10) (Carriage return + Line Feed). Dengan demikian, Anda dapat membuat pernyataan REPLACE dengan teks yang ingin Anda ganti dengan baris baru.

REPLACE(MyField, CHAR(13) + CHAR(10), 'something else')
Cerebrus
sumber
9
ini tidak sama dengan jawaban yang diterima; jawaban yang diterima menghapus kombinasi {13, 10}. ini hanya menghilangkan kombinasi spesifik dari 13 kemudian 10. Itu tidak membuat perbedaan untuk akhir baris windows, tetapi pengkodean lainnya akan terjawab di sini.
Andrew Hill
24

Untuk melakukan apa yang diinginkan kebanyakan orang, buat placeholder yang bukan karakter pemecah garis yang sebenarnya. Maka Anda benar-benar dapat menggabungkan pendekatan untuk:

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

Dengan cara ini Anda hanya mengganti sekali. Pendekatan:

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

Berfungsi bagus jika Anda hanya ingin menyingkirkan karakter CRLF, tetapi jika Anda menginginkan placeholder, seperti
atau sesuatu, maka pendekatan pertama sedikit lebih akurat.

daging babi
sumber
6

Jika tipe data kolom Anda adalah ' teks ' maka Anda akan mendapatkan pesan kesalahan sebagai

Msg 8116, Level 16, Negara 1, Baris 2 Teks tipe data argumen tidak valid untuk argumen 1 fungsi ganti.

Dalam hal ini Anda perlu melemparkan teks sebagai nvarchar dan kemudian ganti

SELECT REPLACE(REPLACE(cast(@str as nvarchar(max)), CHAR(13), ''), CHAR(10), '')
akd
sumber
Ok, ini terlihat bagus. Sekarang, bagaimana jika apa yang saya coba ganti adalah "! Crlf" dan ya itu adalah karakter spasi setelah! Crlf. Kekhawatirannya adalah ini terjadi di tengah-tengah string, dapatkah saya pergi dengan: SELECT REPLACE (REPLACE (cast (@str as nvarchar (MAX)), CHAR (33), CHAR (13), CHAR (10), CHAR (32), '') atau apakah saya menulis ini dengan tidak benar? String terlihat seperti ini: izinkan penyerang jarak jauh untuk mem-bypass mekanisme perlindungan kotak pasir dan mendapatkan hak istimewa melalui situs web kerajinan yang diakses dengan Internet Explorer, Fokus pada kata t! topi ... itu adalah tempat saya kesulitan
bbcompent1
3

Jika Anda memiliki masalah di mana Anda hanya ingin menghapus mengikuti karakter, Anda dapat mencoba ini:

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

Ini memecahkan masalah yang saya miliki dengan alamat tempat prosedur membuat bidang dengan jumlah baris tetap, bahkan jika baris itu kosong. Untuk menghemat ruang dalam laporan SSRS saya, saya memotongnya.

DaveX
sumber
1

Jika Anda memiliki prosedur terbuka dengan menggunakan sp_helptext maka cukup salin semua teks dalam kueri sql baru dan tekan tombol ctrl + h menggunakan ekspresi reguler untuk mengganti dan meletakkan ^ \ n di bidang cari ganti dengan kosong. untuk melihat gambar lebih detail. masukkan deskripsi gambar di sini

Rohan
sumber
1

Untuk solusi @Cerebrus: untuk H2 untuk string "+" tidak didukung. Begitu:

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

Jawaban yang diposting di atas / sebelumnya yang dilaporkan menggantikan CHAR (13) CHAR (10) carriage return:

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

Tidak akan pernah mendapatkan REPLACE(MyField, CHAR(13) + CHAR(10), 'something else')bagian dari kode dan akan mengembalikan hasil yang tidak diinginkan:

'something else''something else'

Dan BUKAN hasil yang diinginkan dari satu:

'something else'

Itu membutuhkan skrip REPLACE untuk ditulis ulang seperti itu:

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

Saat aliran pertama menguji pernyataan REPLACE Kiri Pertama / Terjauh, maka jika gagal akan terus menguji pernyataan REPLACE berikutnya.

Mike
sumber