Reemplazar una nueva línea en TSQL


Me gustaría reemplazar (o eliminar) un carácter de nueva línea en una cadena TSQL. Alguna Idea?

Lo obvio

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

Simplemente no lo hará...

 342
Author: Blorgbeard, 2009-06-04

9 answers

En realidad, una nueva línea en un comando SQL o cadena de script puede ser cualquiera de CR, LF o CR+LF. Para obtenerlos todos, necesitas algo como esto:

SELECT REPLACE(REPLACE(@str, CHAR(13), ''), CHAR(10), '')
 689
Author: RBarryYoung,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-04 03:36:22
REPLACE(@string, CHAR(13) + CHAR(10), '')
 136
Author: Mitch Wheat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-05 14:15:58

La Nueva línea en T-SQL está representada por CHAR(13) & CHAR(10) (Retorno de carro + Avance de línea). En consecuencia, puede crear una instrucción REPLACE con el texto con el que desea reemplazar la nueva línea.

REPLACE(MyField, CHAR(13) + CHAR(10), 'something else')
 31
Author: Cerebrus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-04 16:17:14

Puedo llegar un año tarde a la fiesta, pero trabajo en consultas & MS-SQL todos los días, y me cansé de las funciones integradas LTRIM() & RTRIM() (y siempre tener que llamarlas juntas), y de no capturar datos 'sucios' que tenían nuevas líneas al final, así que decidí que era hora de implementar una mejor función TRIM. Me gustaría recibir comentarios de los compañeros!

Descargo de responsabilidad : esto en realidad elimina (reemplaza con un solo espacio en blanco) las formas extendidas de espacios en blanco (tab, line-feed, retorno de carro, etc.), por lo que ha sido renombrado como "CleanAndTrim" de mi respuesta original. La idea aquí es que su cadena no necesita tales caracteres de espacio en blanco extra especiales dentro de ella, por lo que si no aparecen en la cabeza/cola, deben reemplazarse con un espacio plano. Si guardaste estos caracteres a propósito en tu cadena (por ejemplo, tu columna de datos en la que estás a punto de ejecutar esto), ¡NO LO HAGAS! Mejorar esta función o escribir su propia que, literalmente, solo elimina los caracteres de los extremos de la cadena, no del 'cuerpo'.

Bien, ahora que el descargo de responsabilidad está actualizado, aquí está el código.

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

Salud!

Otro Descargo de responsabilidad: El salto de línea típico de Windows es CR + LF, por lo que si su cadena contiene esos, terminaría reemplazándolos con espacios "dobles".

ACTUALIZAR, 2016: Una nueva versión que le da la opción de reemplazar esos caracteres especiales de espacios en blanco con otros caracteres de ¡tú eliges! Esto también incluye comentarios y la solución para el emparejamiento de Windows CR+LF, es decir, reemplaza ese par de caracteres específico con una sola sustitución.

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
 28
Author: NateJ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-12 18:16:04

Para hacer lo que la mayoría de la gente querría, cree un marcador de posición que no sea un carácter real de salto de línea. Entonces usted puede realmente combinar los enfoques para:

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

De esta manera se reemplaza solo una vez. El enfoque de:

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

Funciona muy bien si solo desea deshacerse de los caracteres CRLF, pero si desea un marcador de posición, como
o algo, entonces el primer enfoque es un poco más preciso.

 21
Author: porkandcheese,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-08 20:49:54

Si su tipo de datos de columna es ' text ', entonces obtendrá un mensaje de error como

Msg 8116, Nivel 16, Estado 1, Línea 2 Argumento tipo de datos el texto es no válido para el argumento 1 de la función replace.

En este caso, debe convertir el texto como nvarchar y luego reemplazar

SELECT REPLACE(REPLACE(cast(@str as nvarchar(max)), CHAR(13), ''), CHAR(10), '')
 4
Author: akd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-23 10:32:34

Si tiene un problema en el que solo desea eliminar caracteres finales, puede probar esto:

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

Esto resolvió un problema que tuve con direcciones donde un procedimiento creó un campo con un número fijo de líneas, incluso si esas líneas estaban vacías. Para ahorrar espacio en mi informe SSRS, los corté.

 3
Author: DaveX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-16 21:11:53

Si tiene un procedimiento abierto con el uso de sp_helptext, simplemente copie todo el texto en la nueva consulta sql y presione ctrl+h use la expresión regular para reemplazar y coloque ^\n en el campo buscar reemplazar con blanco . para más detalle, compruebe la imagen. introduzca aquí la descripción de la imagen

 1
Author: Rohan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-11 13:05:54

To @Cerebrus solution: for H2 for strings "+" is not suupported. Entonces:

REPLACE(string, CHAR(13) || CHAR(10), 'replacementString')
 0
Author: GKislin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-29 10:44:04