2009-06-04 4 views
313

Vorrei sostituire (o rimuovere) un carattere di nuova riga in una stringa TSQL. Qualche idea?Sostituire una nuova riga in TSQL

L'ovvio

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

proprio non lo farà ...

risposta

633

In realtà una nuova riga in un comando SQL o una stringa di script può essere qualsiasi di CR, LF o CR + LF. Per farli tutti, avete bisogno di qualcosa di simile:

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

@NielsBrinch Che funzionerà bene finché questo è l'unico tipo di interruzione di riga nelle stringhe. Ma SQL Server supporta tutti e tre i tipi. In effetti, se hai mai estratto tutte le stored procedure di sistema e le viste con script, puoi trovare le istanze di tutti e tre utilizzati da Microsoft. – RBarryYoung

+0

Questo ha funzionato per me b/c prima di apportare questa modifica alla copia e incollare i dati della colonna avrebbe il cursore alla fine del testo con due spazi. Dopo aver effettuato questa modifica, copia e incolla nel blocco note il cursore si trovava direttamente alla fine del testo. Stava causando un problema per me b/c nella nostra GUI di front-end che il nuovo line char stava mostrando. – natur3

+4

Se il tipo di dati della colonna è testo, è necessario eseguire il cast su nvarchar, quindi sostituire SELECT REPLACE (REPLACE (cast (@str as nvarchar (max)), CHAR (13), ''), CHAR (10), '') – akd

132
REPLACE(@string, CHAR(13) + CHAR(10), '') 
+1

Questo era il metodo che ho provato prima, ma non funzionava in modo affidabile per tutti i dati. @RBarryYoung ha proprio sopra. –

30

La nuova riga in T-SQL è rappresentato da CHAR (13) & CHAR (10) (Carriage ritorno + Avanzamento riga). Di conseguenza, è possibile creare un'istruzione REPLACE con il testo con cui si desidera sostituire la nuova riga.

+0

+ 1, ho accettato Mitch Wheat perché l'ha inventato per primo (anche se la funzione chr non esiste nel mio tsql) – Peter

+1

Ehi, nessun problema! Mitch oscilla come al solito. Pochi ragazzi possono essere veloci come lui. ;-) – Cerebrus

+6

questo non è esattamente la stessa della risposta accettata; la risposta accettata rimuove qualsiasi combinazione di {13, 10}. questo rimuove solo la combinazione specifica di 13 quindi di 10. Non crea un diff per le terminazioni di linea di Windows, ma qui manca un'altra codifica. –

20

Per fare quello che la maggior parte la gente vorrebbe, creare un segnaposto che non è una rottura carattere riga effettiva. Quindi è possibile combinare gli approcci per:

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

In questo modo si sostituisce solo una volta. L'approccio di:

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

funziona grande se si vuole solo sbarazzarsi dei caratteri CRLF, ma se si vuole un segnaposto, come ad esempio
o qualcosa del genere, quindi il primo approccio è un po 'più accurata.

+1

Questo aiuta molto, ho avuto un problema con CHAR (10) e l'ho già risolto. –

23

io possa essere un anno di ritardo alla festa, ma lavorare su query & MS-SQL ogni giorno, e mi sono stancato delle funzioni built-in LTRIM() & RTRIM() (e avendo sempre di chiamarli insieme), e di non rilevare i dati "sporchi" che avevano newline alla fine, quindi ho deciso che era giunto il momento di implementare una funzione di TRIM migliore. Mi piacerebbe ricevere il feedback dei colleghi!

responsabilità: questo in realtà rimuove (sostituisce con un singolo spazio bianco) forme estese di spazi bianchi (tab, line-feed, ritorno a capo, etc.), quindi è stato rinominato come "CleanAndTrim" dal mio originale risposta. L'idea qui è che la tua stringa non ha caratteri extra-speciali all'interno di esso, e quindi se non si verificano in testa/coda, dovrebbero essere sostituiti con uno spazio semplice. Se hai memorizzato intenzionalmente tali caratteri nella stringa (ad esempio, la colonna di dati su cui stai per eseguirla), NON FARLO! Migliora questa funzione o scrivi la tua che rimuove letteralmente quei caratteri dai punti finali della stringa, non dal 'corpo'.

Ok, ora che la dichiarazione di non responsabilità è aggiornata, ecco il codice.

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

Un'altra responsabilità: Il tipico linea-break Windows è CR + LF, quindi se la stringa contiene quelli, si sarebbe finito la loro sostituzione con spazi "doppie".

UPDATE 2016: Una nuova versione che ti dà la possibilità di sostituire i caratteri speciali-spazio bianco con altri personaggi della vostra scelta! Ciò include anche il commento e il work-around per l'accoppiamento di Windows CR + LF, cioè sostituisce quella specifica coppia di caratteri con una sostituzione singola.

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 
+0

Gli utenti precedenti, si prega di notare il cambiamento e la dichiarazione di non responsabilità - e mi scuso per le ipotesi iniziali sull'uso e lo scopo. – NateJ

+0

Nuovo aggiornamento! I casi di prova possono essere trovati qui: http://sqlfiddle.com/#!6/585a2/1/0 - SQLFiddle sembrava soffocare sulla mia effettiva esecuzione dei casi di test, così invece, ho costruito un "test-case query builder "tabella e fornisci le 9 istruzioni per copiare e incollare nella tua finestra SSMS da eseguire (dopo aver creato lo schema, ovviamente, la funzione e la tabella TestStrings). – NateJ

3

Se si dispone di un problema in cui si desidera rimuovere finali caratteri, si può provare questo:

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 

Questo ha risolto un problema che ho avuto con gli indirizzi in cui una procedura creato un campo con un numero fisso di linee, anche se quelle linee erano vuote. Per risparmiare spazio nel mio rapporto SSRS, li ho abbattuti.

3

Se il tipo di dati della colonna è 'testo' allora si ottiene un messaggio di errore come

Msg 8116, livello 16, stato 1, riga 2 argomento di tipo di dati di testo è valido per l'argomento 1 di sostituire la funzione.

In questo caso è necessario lanciare il testo come nvarchar e quindi sostituire

SELECT REPLACE(REPLACE(cast(@str as nvarchar(max)), CHAR(13), ''), CHAR(10), '') 
+0

Bel avvertimento! Grazie! –

+0

Ok, sembra fantastico. Ora, cosa succede se quello che sto cercando di sostituire è "! Crlf" e sì che è un carattere di spazio dopo il! Crlf. La preoccupazione è che questo si verifichi nel mezzo della stringa, potrei farla franca: SELEZIONA SOSTITUISCI (REPLACE (cast (@str as nvarchar (MAX)), CHAR (33), CHAR (13), CHAR (10) , CHAR (32), '') o ho scritto in modo errato? La stringa è simile a questa: consentire agli aggressori remoti di bypassare un meccanismo di protezione sandbox e ottenere privilegi tramite un sito Web creato! T! con Internet Explorer, Concentrati sulla parola t! hat ... è il mio punto problematico. – bbcompent1

1

Se si dispone di avere procedura aperta con l'utilizzo di sp_helptext poi basta copiare tutto il testo nella nuova query SQL e premere Ctrl + h il pulsante usa l'espressione regolare per sostituire e inserisce^\ n nel campo di ricerca sostituisce con lo spazio vuoto. per maggiori dettagli controlla l'immagine. enter image description here