Cómo insertar un salto de línea en una cadena VARCHAR / NVARCHAR de SQL Server

562

No vi ninguna pregunta similar sobre este tema, y ​​tuve que investigar esto para algo en lo que estoy trabajando en este momento. Pensé en publicar la respuesta en caso de que alguien más tuviera la misma pregunta.

Mark Struzinski
fuente
8
Para probar su salida, si usa SSMS, asegúrese de que la opción Retener CR / LF al copiar o guardar esté marcada, de lo contrario, todos los resultados pegados perderán el avance de línea. Puede encontrar esto en configuraciones, resultados de consultas, servidor sql, resultados en cuadrícula.
Stefanos Zilellis
1
@StefanosZilellis y asegúrese de abrir una nueva ventana de consulta para que los cambios de configuración surtan efecto.
Don Cheadle

Respuestas:

597

char(13)es CR. Para los saltos de línea de estilo DOS / Windows CRLF, desea char(13)+char(10), como:

'This is line 1.' + CHAR(13)+CHAR(10) + 'This is line 2.'
Sören Kuklau
fuente
28
char (13) + char (10) no funcionó para mí en Windows. Acabo de usar char (10)
nima
66
@Nima: Algunas aplicaciones usarán una u otra o ambas para mostrar una nueva línea, sin embargo, muchas aplicaciones a las que puede enviar este texto requerirán que ambas aparezcan sucesivamente para indicar una nueva línea. Me parece seguro usar ambos. Puede enumerar aquí para cuáles de sus aplicaciones no funciona. Prefiero los valores hexadecimales CHAR (0x0D) + CHAR (0x0A), pero a cada uno lo suyo.
MikeTeeVee
2
Utilicé este método con éxito, pero me encontré con un problema: una vez que tenga más de 480 +, SQL Server comenzará a quejarse de que su consulta está demasiado anidada. En cambio, mi solución fue utilizar la respuesta de Rob Cooper, pero con un token mucho más largo y oscuro.
Marcus Downing
55
Proporcionar \ r \ n significaría reconocer que existen expresiones regulares y que hay usuarios capaces de comprenderlas y usarlas.
wwmbes
10
@HBlackorby \ r y \ n son anteriores a Java-cualquier cosa por décadas con su uso en C; y son estándar en Python, PHP, Ruby, C ++, C #, etc ...
Uueerdo
286

Encontré la respuesta aquí: http://blog.sqlauthority.com/2007/08/22/sql-server-t-sql-script-to-insert-carriage-return-and-new-line-feed-in- código/

Simplemente concatene la cadena e inserte un lugar CHAR(13)donde desee su salto de línea.

Ejemplo:

DECLARE @text NVARCHAR(100)
SET @text = 'This is line 1.' + CHAR(13) + 'This is line 2.'
SELECT @text

Esto imprime lo siguiente:

Esta es la línea 1.
Esta es la línea 2.

Mark Struzinski
fuente
11
ACTUALIZACIÓN: olvídalo. Se inserta muy bien. Es el estudio de administración el que reemplaza las pestañas y las nuevas líneas con espacios para visibilidad
Daniel Dolz
12
Parece que necesita usar PRINT @text en lugar de SELECT para obtener este resultado.
QMaster
3
Por cierto: también puede usar NCHAR(0x1234)para obtener un carácter unicode. No es necesario para insertar saltos de línea, pero puede ser útil si uno debe insertar / buscar caracteres unicode.
Paul Groke
3
En SQL Server 2016, solo veo imprimir las dos líneas si las uso en printlugar de select, por ejemplo:DECLARE @text NVARCHAR(100); SET @text = 'This is line 1.' + CHAR(13) + 'This is line 2.'; print @text;
devinbost
77
Para probar su salida, si usa SSMS, asegúrese de que la opción Retener CR / LF al copiar o guardar esté marcada, de lo contrario, todos los resultados pegados perderán el avance de línea. Puede encontrar esto en configuraciones, resultados de consultas, servidor sql, resultados en cuadrícula.
Don Cheadle
81

Otra forma de hacer esto es como tal:

INSERT CRLF SELECT 'fox 
jumped'

Es decir, simplemente insertando un salto de línea en su consulta mientras lo escribe agregará el salto similar a la base de datos. Esto funciona en SQL Server Management Studio y Query Analyzer. Creo que esto también funcionará en C # si usa el signo @ en las cadenas.

string str = @"INSERT CRLF SELECT 'fox 
    jumped'"
Frank V
fuente
14
En otras palabras, la sintaxis del lenguaje SQL simplemente permite avances de línea sin formato en cadenas literales. Funciona de esta manera en todos los motores que he probado (SQL Server, Oracle, MySQL, PostgreSQL y SQLite).
Álvaro González
a veces esto deja de funcionar aleatoriamente si lo usa en procedimientos almacenados
DaFi4
25

Ejecute esto en SSMS, muestra cómo los saltos de línea en el propio SQL se convierten en parte de los valores de cadena que abarcan líneas:

PRINT 'Line 1
Line 2
Line 3'
PRINT ''

PRINT 'How long is a blank line feed?'
PRINT LEN('
')
PRINT ''

PRINT 'What are the ASCII values?'
PRINT ASCII(SUBSTRING('
',1,1))
PRINT ASCII(SUBSTRING('
',2,1))

Resultado:
Línea 1
Línea 2
Línea 3

¿Cuánto dura un avance de línea en blanco?
2

¿Cuáles son los valores ASCII?
13
10

O si prefiere especificar su cadena en una línea (¡casi!) Podría emplearla de REPLACE()esta manera (opcionalmente, usarla CHAR(13)+CHAR(10)como reemplazo):

PRINT REPLACE('Line 1`Line 2`Line 3','`','
')
AjV Jsy
fuente
16

Siguiendo un Google ...

Tomando el código del sitio web:

CREATE TABLE CRLF
    (
        col1 VARCHAR(1000)
    )

INSERT CRLF SELECT 'The quick brown@'
INSERT CRLF SELECT 'fox @jumped'
INSERT CRLF SELECT '@over the '
INSERT CRLF SELECT 'log@'

SELECT col1 FROM CRLF

Returns:

col1
-----------------
The quick brown@
fox @jumped
@over the
log@

(4 row(s) affected)


UPDATE CRLF
SET col1 = REPLACE(col1, '@', CHAR(13))

Parece que se puede hacer reemplazando un marcador de posición con CHAR (13)

Buena pregunta, nunca lo hice yo mismo :)

Rob Cooper
fuente
44
Pero si el texto tiene una dirección de correo electrónico? "[email protected]" se convierte en "jon bob.com" (con una nueva línea en el vestido electrónico)
intrepidis
44
@ChrisNash luego use un marcador de posición diferente (por ejemplo, "|", "~" o varios caracteres, "! #!"). Vea esta respuesta a continuación: stackoverflow.com/a/31179/179311 .
bradlis7
1
"CONCAT (CHAR (13), CHAR (10))" ("\ r \ n") sería mejor para el entorno de Windows, que supongo es el caso (SQL Server) cs.toronto.edu/~krueger/csc209h/ tut / line-endings.html
d.popov
12

Llegué aquí porque me preocupaba que los cr-lfs que especifiqué en las cadenas de C # no se mostraran en las respuestas de consulta de SQl Server Management Studio.

Resulta que están allí, pero no se muestran.

Para "ver" el cr-lfs, use la instrucción print como:

declare @tmp varchar(500)    
select @tmp = msgbody from emailssentlog where id=6769;
print @tmp
Bruce Allen
fuente
4

Aquí hay una función C # que antepone una línea de texto a un blob de texto existente, delimitado por CRLF, y devuelve una expresión T-SQL adecuada para INSERTu UPDATEoperaciones. Tiene algo de nuestro manejo de errores patentado, pero una vez que lo elimine, puede ser útil, espero que sea así.

/// <summary>
/// Generate a SQL string value expression suitable for INSERT/UPDATE operations that prepends
/// the specified line to an existing block of text, assumed to have \r\n delimiters, and
/// truncate at a maximum length.
/// </summary>
/// <param name="sNewLine">Single text line to be prepended to existing text</param>
/// <param name="sOrigLines">Current text value; assumed to be CRLF-delimited</param>
/// <param name="iMaxLen">Integer field length</param>
/// <returns>String: SQL string expression suitable for INSERT/UPDATE operations.  Empty on error.</returns>
private string PrependCommentLine(string sNewLine, String sOrigLines, int iMaxLen)
{
    String fn = MethodBase.GetCurrentMethod().Name;

    try
    {
        String [] line_array = sOrigLines.Split("\r\n".ToCharArray());
        List<string> orig_lines = new List<string>();
        foreach(String orig_line in line_array) 
        { 
            if (!String.IsNullOrEmpty(orig_line))  
            {  
                orig_lines.Add(orig_line);    
            }
        } // end foreach(original line)

        String final_comments = "'" + sNewLine + "' + CHAR(13) + CHAR(10) ";
        int cum_length = sNewLine.Length + 2;
        foreach(String orig_line in orig_lines)
        {
            String curline = orig_line;
            if (cum_length >= iMaxLen) break;                // stop appending if we're already over
            if ((cum_length+orig_line.Length+2)>=iMaxLen)    // If this one will push us over, truncate and warn:
            {
                Util.HandleAppErr(this, fn, "Truncating comments: " + orig_line);
                curline = orig_line.Substring(0, iMaxLen - (cum_length + 3));
            }
            final_comments += " + '" + curline + "' + CHAR(13) + CHAR(10) \r\n";
            cum_length += orig_line.Length + 2;
        } // end foreach(second pass on original lines)

        return(final_comments);


    } // end main try()
    catch(Exception exc)
    {
        Util.HandleExc(this,fn,exc);
        return("");
    }
}
Carl Niedner
fuente
4

Yo diría que

concat('This is line 1.', 0xd0a, 'This is line 2.')

o

concat(N'This is line 1.', 0xd000a, N'This is line 2.')
Ken Kin
fuente
3

Esto siempre es genial, porque cuando obtienes listas exportadas de, digamos Oracle, obtienes registros que abarcan varias líneas, lo que a su vez puede ser interesante para, por ejemplo, archivos cvs, así que ten cuidado.

De todos modos, la respuesta de Rob es buena, pero aconsejaría usar algo más que @, intente algunos más, como §§ @@ §§ o algo así, de modo que tenga la posibilidad de un poco de singularidad. (Pero aún así, recuerda la longitud del campo varchar/ en el nvarcharque estás insertando ...)

neslekkiM
fuente
3

Todas estas opciones funcionan según su situación, pero es posible que no vea que ninguna de ellas funciona si está utilizando SSMS (como se menciona en algunos comentarios, SSMS oculta CR / LF)

Entonces, en lugar de conducir por la curva, verifique esta configuración en

Tools | Options

que reemplazará el

Trubs
fuente