522 votes

Remplacer un saut de ligne en TSQL

Je voudrais remplacer (ou supprimer) un caractère de nouvelle ligne dans une chaîne TSQL. Une idée ?

L'évidence

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

ne le fera pas...

1027voto

RBarryYoung Points 23349

En fait, une nouvelle ligne dans une commande SQL ou une chaîne de caractères script peut être une CR, LF ou CR+LF. Pour les obtenir toutes, vous avez besoin de quelque chose comme ceci :

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

5 votes

@NielsBrinch Cela fonctionnera parfaitement tant que ce sera le seul type de retour à la ligne dans vos chaînes de caractères. Mais SQL Server prend en charge les trois types. En fait, si vous avez déjà extrait toutes les procédures stockées et les vues scriptées du système, vous pouvez trouver des exemples des trois types utilisés par Microsoft lui-même.

0 votes

Cela a fonctionné pour moi, car avant de faire ce changement, le curseur se trouvait à la fin du texte avec deux espaces lorsque je copiais et collais les données de la colonne. Après avoir effectué cette modification, le curseur se trouvait directement à la fin du texte lorsque je copiais et collais dans le bloc-notes. Cela me posait un problème car, dans notre interface graphique frontale, le caractère de la nouvelle ligne apparaissait.

10 votes

Si le type de données de la colonne est du texte, vous devez d'abord effectuer un cast en nvarchar puis remplacer SELECT REPLACE(REPLACE(cast(@str as nvarchar(max)), CHAR(13), ''), CHAR(10), '')

165voto

Mitch Wheat Points 169614
REPLACE(@string, CHAR(13) + CHAR(10), '')

2 votes

C'est la méthode que j'ai d'abord essayée, mais elle n'a pas fonctionné de manière fiable pour toutes les données. @RBarryYoung a raison ci-dessus.

1 votes

Merci, j'ai dû modifier un peu cette méthode pour qu'elle me convienne, dans mon cas, c'est : replace(REPLACE(@string, CHAR(13) , ''),CHAR(10), '')

0 votes

Merci, cela a fonctionné, la première réponse ne l'a pas fait pour une raison quelconque.

55voto

NateJ Points 426

J'ai peut-être un an de retard sur la fête, mais je travaille sur des requêtes et MS-SQL tous les jours, et j'en ai eu assez des fonctions intégrées LTRIM() et RTRIM() (et de devoir toujours les appeler ensemble), et de ne pas attraper les données "sales" qui ont des nouvelles lignes à la fin, donc j'ai décidé qu'il était grand temps d'implémenter une meilleure fonction TRIM. Je serais heureux de recevoir les commentaires de mes pairs !

Avis de non-responsabilité : en fait, ceci supprime (remplace par un seul espace) les formes étendues d'espace (tabulation, saut de ligne, retour chariot, etc.), il a donc été renommé "CleanAndTrim" depuis ma réponse originale. L'idée ici est que votre chaîne de caractères n'est pas besoin de comme des caractères d'espacement spéciaux supplémentaires à l'intérieur, et donc s'ils n'apparaissent pas en tête/queue, ils doivent être remplacés par un espace simple. Si vous avez volontairement stocké de tels caractères dans votre chaîne (disons, votre colonne de données sur laquelle vous êtes sur le point d'exécuter cette fonction), NE LE FAITES PAS ! Améliorez cette fonction ou écrivez votre propre fonction qui supprime littéralement ces caractères des extrémités de la chaîne, et non du "corps".

Ok, maintenant que l'avertissement est mis à jour, voici le 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

A la vôtre !

Un autre avertissement : Le saut de ligne typique de Windows est CR+LF, donc si votre chaîne en contient, vous finirez par les remplacer par des espaces "doubles".

MISE À JOUR, 2016 : Une nouvelle version qui vous donne l'option de remplacer ces caractères spéciaux d'espacement par autre les personnages de votre choix ! Ceci inclut également des commentaires et la solution de contournement pour la paire CR+LF de Windows, c'est-à-dire le remplacement de cette paire de caractères spécifique par une seule 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

0 votes

Anciens utilisateurs, veuillez noter le changement et l'avertissement - et je m'excuse pour les hypothèses initiales sur l'utilisation et l'objectif.

1 votes

Nouvelle mise à jour ! Les cas de test peuvent être trouvés ici : sqlfiddle.com/#!6/585a2/1/0 -- SQLFiddle a semblé s'étouffer lors de l'exécution des cas de test, donc à la place, j'ai construit un tableau "constructeur de requêtes de cas de test" et je vous donne les 9 instructions à copier-coller dans votre propre fenêtre SSMS pour les exécuter (après avoir créé le schéma bien sûr, c'est-à-dire la fonction et le tableau TestStrings).

3 votes

Microsoft a tellement aimé votre fonction TRIM qu'elle l'a incluse dans SQL Server 2017 ;)

37voto

Cerebrus Points 18045

Le Newline dans T-SQL est représenté par CHAR(13) & CHAR(10) (Carriage Return + Line Feed). Par conséquent, vous pouvez créer une instruction REPLACE avec le texte par lequel vous souhaitez remplacer la nouvelle ligne.

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

12 votes

Ce n'est pas tout à fait la même chose que la réponse acceptée ; la réponse acceptée supprime toute combinaison de {13, 10}. ceci ne supprime que la combinaison spécifique de 13 puis 10. Il n'y a pas de différence pour les fins de ligne de Windows, mais d'autres encodages seront manqués ici.

32voto

porkandcheese Points 91

Pour faire ce que la plupart des gens voudraient, créez un caractère de remplacement qui n'est pas un véritable caractère de rupture de ligne. Vous pouvez alors combiner les deux approches :

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

De cette façon, vous ne remplacez qu'une seule fois. L'approche de :

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

Cela fonctionne très bien si vous voulez simplement vous débarrasser des caractères CRLF, mais si vous voulez un espace réservé, tel que

<br/>

ou autre, alors la première approche est un peu plus précise.

0 votes

Ce que j'ai fait, c'est qu'à la place de '', j'ai remplacé les sauts de ligne par un espace. Ce qui est bien si vous avez CR ou LF, vous n'aurez qu'un espace, mais si vous avez un CRLF, vous en aurez deux. J'ai donc ajouté un autre remplacement pour remplacer les espaces doubles par un espace simple : REPLACE(REPLACE(REPLACE(ClientName, CHAR(13), ' '), CHAR(10), ' '),' ',' ')

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X