Como inserir uma quebra de linha em uma seqüência de caracteres SQL Server VARCHAR / NVARCHAR

562

Não vi perguntas semelhantes sobre esse tópico e tive que pesquisar isso para algo em que estou trabalhando no momento. Pensei em postar a resposta para o caso de alguém ter a mesma pergunta.

Mark Struzinski
fonte
8
Para testar sua saída, se estiver usando o SSMS, verifique se a opção Reter CR / LF ao copiar ou salvar está marcada, caso contrário, todos os resultados colados perderão o avanço de linha. Você encontra isso em configurações, resultados da consulta, servidor sql, resultados na grade.
Stefanos Zilellis
1
@StefanosZilellis e certifique-se de abrir uma nova janela de consulta para que as alterações na configuração entrem em vigor.
Don Cheadle

Respostas:

597

char(13)é CR. Para CRLFquebras de linha no estilo DOS / Windows , você deseja char(13)+char(10):

'This is line 1.' + CHAR(13)+CHAR(10) + 'This is line 2.'
Sören Kuklau
fonte
28
char (13) + char (10) não funcionou para mim no Windows. Eu apenas usei char (10)
nima
6
@ Nima: Alguns aplicativos usarão um ou outro ou ambos para mostrar uma nova linha; no entanto, muitos aplicativos para os quais você pode enviar este texto exigirão que ambos apareçam em sucessão para significar uma nova linha. Acho seguro usar os dois. Você pode listar aqui para quais aplicativos ele não funciona. Eu prefiro os valores hexadecimais CHAR (0x0D) + CHAR (0x0A), mas cada um na sua.
21713 MikeTeeVee
2
Usei esse método com êxito, mas tive um problema com ele: quando você tiver mais de 480 +, o SQL Server começará a reclamar que sua consulta está muito aninhada. Em vez disso, minha solução foi usar a resposta de Rob Cooper, mas com um token muito mais longo e mais obscuro.
Marcus Downing
5
Fornecer \ r \ n significaria reconhecer que existem expressões regulares e que existem usuários capazes de entendê-las e usá-las.
Wwmbes
10
@HBlackorby \ re \ n precedem Java-qualquer coisa há décadas com seu uso em C; e são padrão em Python, PHP, Ruby, C ++, C #, etc ...
Uueerdo
286

Encontrei a resposta aqui: http://blog.sqlauthority.com/2007/08/22/sql-server-t-sql-script-to-insert-carriage-return-and-new-line-feed-in- código/

Você apenas concatena a string e insere um CHAR(13)onde deseja que sua quebra de linha.

Exemplo:

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

Isso imprime o seguinte:

Esta é a linha 1.
Esta é a linha 2.

Mark Struzinski
fonte
11
ATUALIZAÇÃO: esqueça. Insere muito bem. Estúdio de gestão é o único que substitui tabulações e novas linhas com espaços para a visibilidade
Daniel Dolz
12
Parece que você precisa usar PRINT @text em vez de SELECT para obter esse resultado.
Qmaster
3
BTW: Você também pode usar NCHAR(0x1234)para obter um caractere unicode. Não é necessário inserir quebras de linha, mas pode ser útil se for necessário inserir / procurar caracteres unicode.
Paul Groke
3
No SQL Server 2016, só vejo ele imprimir as duas linhas se eu usar em printvez de select, como:DECLARE @text NVARCHAR(100); SET @text = 'This is line 1.' + CHAR(13) + 'This is line 2.'; print @text;
devinbost
7
Para testar sua saída, se estiver usando o SSMS, verifique se a opção Reter CR / LF ao copiar ou salvar está marcada, caso contrário, todos os resultados colados perderão o avanço de linha. Você encontra isso em configurações, resultados da consulta, servidor sql, resultados na grade.
Don Cheadle
81

Outra maneira de fazer isso é:

INSERT CRLF SELECT 'fox 
jumped'

Ou seja, simplesmente inserir uma quebra de linha na sua consulta enquanto a escreve adicionará a quebra semelhante ao banco de dados. Isso funciona no SQL Server Management studio e no Query Analyzer. Acredito que isso também funcionará em c # se você usar o sinal @ nas strings.

string str = @"INSERT CRLF SELECT 'fox 
    jumped'"
Frank V
fonte
14
Em outras palavras, a sintaxe da linguagem SQL simplesmente permite feeds de linha bruta em strings literais. Funciona assim em todos os mecanismos que eu tentei (SQL Server, Oracle, MySQL, PostgreSQL e SQLite).
Álvaro González
às vezes isso sai aleatoriamente de funcionar se você usá-lo em procedimentos armazenados
DaFi4
25

Execute isso no SSMS, mostra como as quebras de linha no próprio SQL se tornam parte dos valores de sequência que abrangem linhas:

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:
Linha 1
Linha 2
Linha 3

Quanto tempo dura um feed de linha em branco?
2

Quais são os valores ASCII?
13
10

Ou, se preferir especificar sua string em uma linha (quase!), Você pode empregar REPLACE()assim (opcionalmente use CHAR(13)+CHAR(10)como substituto):

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

Após um Google ...

Tomando o código do site:

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 isso pode ser feito substituindo um espaço reservado por CHAR (13)

Boa pergunta, nunca fiz isso sozinho :)

Rob Cooper
fonte
4
Mas se o texto tiver um endereço de e-mail? "[email protected]" se torna "jon bob.com" (com uma nova linha no e-vestido)
intrepidis
4
@ChrisNash use um espaço reservado diferente (por exemplo, "|", "~" ou vários caracteres, "! #!"). Veja esta resposta abaixo: stackoverflow.com/a/31179/179311 .
bradlis7
1
"CONCAT (CHAR (13), CHAR (10))" ("\ r \ n") seria melhor para o ambiente Windows, o que suponho ser o caso (SQL Server) cs.toronto.edu/~krueger/csc209h/ tut / line-endings.html
d.popov 29/03/16
12

Cheguei aqui porque estava preocupado com o fato de que os cr-lfs especificados em c # strings não estavam sendo mostrados nas respostas de consulta do SQl Server Management Studio.

Acontece que eles estão lá, mas não estão sendo exibidos.

Para "ver" os cr-lfs, use a instrução print como:

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

Aqui está uma # função C que prepends uma linha de texto para um blob texto existente, delimitado por CRLFs, e retorna uma expressão T-SQL apropriado para INSERTou UPDATEoperações. Ele contém alguns dos nossos erros proprietários de manipulação, mas uma vez que você o reproduz, pode ser útil - espero que sim.

/// <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
fonte
4

eu diria

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

ou

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

Isso é sempre legal, porque quando você obtém listas exportadas, digamos do Oracle, obtém registros que abrangem várias linhas, o que, por sua vez, pode ser interessante para, por exemplo, arquivos cvs, por isso tome cuidado.

De qualquer forma, a resposta de Rob é boa, mas eu recomendaria usar algo diferente de @, tente um pouco mais, como §§ @@ §§ ou algo assim, para que haja uma chance de alguma singularidade. (Mas ainda assim, lembre-se do tamanho do campo varchar/ nvarcharno qual você está inserindo ..)

neslekkiM
fonte
3

Todas essas opções funcionam dependendo da sua situação, mas você pode não vê-las funcionar se estiver usando o SSMS (conforme mencionado em alguns comentários O SSMS oculta os CR / LFs)

Portanto, em vez de se curvar, verifique esta configuração em

Tools | Options

que substituirá o

Trubs
fonte