So fügen Sie einen Zeilenumbruch in eine SQL Server VARCHAR / NVARCHAR-Zeichenfolge ein

562

Ich habe keine ähnlichen Fragen zu diesem Thema gesehen und musste dies für etwas recherchieren, an dem ich gerade arbeite. Ich dachte, ich würde die Antwort darauf posten, falls jemand anderes die gleiche Frage hätte.

Mark Struzinski
quelle
8
Um Ihre Ausgabe zu testen, stellen Sie bei Verwendung von SSMS sicher, dass die Option CR / LF beim Kopieren oder Speichern beibehalten aktiviert ist. Andernfalls verlieren alle eingefügten Ergebnisse den Zeilenvorschub. Sie finden dies unter Einstellungen, Abfrageergebnisse, SQL Server, Ergebnisse im Raster.
Stefanos Zilellis
1
@StefanosZilellis und stellen Sie sicher, dass Sie ein neues Abfragefenster öffnen, damit die Einstellungsänderungen wirksam werden.
Don Cheadle

Antworten:

597

char(13)ist CR. Für CRLFZeilenumbrüche im DOS- / Windows-Stil möchten Sie Folgendes char(13)+char(10):

'This is line 1.' + CHAR(13)+CHAR(10) + 'This is line 2.'
Sören Kuklau
quelle
28
char (13) + char (10) hat bei mir in Windows nicht funktioniert. Ich habe gerade char (10)
nima
6
@Nima: Einige Anwendungen verwenden die eine oder die andere oder beide, um eine neue Zeile anzuzeigen. Bei vielen Anwendungen, für die Sie diesen Text ausgeben können, müssen jedoch beide nacheinander angezeigt werden, um eine neue Zeile zu kennzeichnen. Ich finde es sicher, beide zu benutzen. Hier können Sie auflisten, für welche Ihrer Apps es nicht funktioniert. Ich bevorzuge die hexadezimalen Werte CHAR (0x0D) + CHAR (0x0A) selbst, aber jedem seine eigenen.
MikeTeeVee
2
Ich habe diese Methode erfolgreich verwendet, bin jedoch auf ein Problem gestoßen: Sobald Sie mehr als 480 haben +, beschwert sich SQL Server, dass Ihre Abfrage zu tief verschachtelt ist. Meine Lösung bestand stattdessen darin, Rob Coopers Antwort zu verwenden, jedoch mit einem viel längeren und dunkeleren Token.
Marcus Downing
5
Das Bereitstellen von \ r \ n würde bedeuten, dass anerkannt wird, dass reguläre Ausdrücke vorhanden sind und dass es Benutzer gibt, die diese verstehen und verwenden können.
wwmbes
10
@HBlackorby \ r und \ n sind um Jahrzehnte älter als Java - alles mit ihrer Verwendung in C; und sind Standard in Python, PHP, Ruby, C ++, C #, etc ...
Uueerdo
286

Ich fand die Antwort hier: http://blog.sqlauthority.com/2007/08/22/sql-server-t-sql-script-to-insert-carriage-return-and-new-line-feed-in- Code/

Sie verketten einfach die Zeichenfolge und fügen eine Stelle ein, CHAR(13)an der Sie Ihren Zeilenumbruch wünschen.

Beispiel:

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

Dies druckt Folgendes aus:

Dies ist Zeile 1.
Dies ist Zeile 2.

Mark Struzinski
quelle
11
UPDATE: Vergiss es. Es fügt gut ein. Es ist das Management Studio, das Tabs und Zeilenumbrüche durch Leerzeichen für Sichtbarkeit ersetzt
Daniel Dolz
12
Es scheint, dass Sie PRINT @text verwenden müssen, anstatt SELECT, um dieses Ergebnis zu erhalten.
QMaster
3
Übrigens: Sie können auch NCHAR(0x1234)ein Unicode-Zeichen abrufen. Nicht zum Einfügen von Zeilenumbrüchen erforderlich, kann jedoch nützlich sein, wenn Unicode-Zeichen eingefügt / gesucht werden müssen.
Paul Groke
3
In SQL Server 2016 werden nur die beiden Zeilen gedruckt, wenn ich printstattdessen selectDECLARE @text NVARCHAR(100); SET @text = 'This is line 1.' + CHAR(13) + 'This is line 2.'; print @text;
Folgendes verwende
7
Um Ihre Ausgabe zu testen, stellen Sie bei Verwendung von SSMS sicher, dass die Option CR / LF beim Kopieren oder Speichern beibehalten aktiviert ist. Andernfalls verlieren alle eingefügten Ergebnisse den Zeilenvorschub. Sie finden dies unter Einstellungen, Abfrageergebnisse, SQL Server, Ergebnisse im Raster.
Don Cheadle
81

Ein anderer Weg, dies zu tun, ist als solcher:

INSERT CRLF SELECT 'fox 
jumped'

Das heißt, durch einfaches Einfügen eines Zeilenumbruchs in Ihre Abfrage während des Schreibens wird der Datenbank ein ähnlicher Zeilenumbruch hinzugefügt. Dies funktioniert in SQL Server Management Studio und Query Analyzer. Ich glaube, dass dies auch in C # funktioniert, wenn Sie das @ -Zeichen für Zeichenfolgen verwenden.

string str = @"INSERT CRLF SELECT 'fox 
    jumped'"
Frank V.
quelle
14
Mit anderen Worten, die Syntax der SQL-Sprache ermöglicht einfach rohe Zeilenvorschübe in Zeichenfolgenliteralen. Dies funktioniert in allen Engines, die ich ausprobiert habe (SQL Server, Oracle, MySQL, PostgreSQL und SQLite).
Álvaro González
manchmal wird dies zufällig beendet, wenn Sie es in gespeicherten Prozeduren verwenden
DaFi4
25

Führen Sie dies in SSMS aus. Es zeigt, wie Zeilenumbrüche in SQL selbst Teil von Zeichenfolgenwerten werden, die sich über Zeilen erstrecken:

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

Ergebnis:
Zeile 1
Zeile 2
Zeile 3

Wie lang ist ein Leerzeilenvorschub?
2

Was sind die ASCII-Werte?
13
10

Oder wenn Sie Ihre Zeichenfolge lieber in einer Zeile angeben möchten (fast!), Können Sie Folgendes verwenden REPLACE()(optional CHAR(13)+CHAR(10)als Ersatz verwenden):

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

Nach einem Google ...

Den Code von der Website übernehmen:

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

Sieht so aus, als könnte man einen Platzhalter durch CHAR ersetzen (13).

Gute Frage, habe es nie selbst gemacht :)

Rob Cooper
quelle
4
Aber wenn der Text eine E-Mail-Adresse enthält? "[email protected]" wird zu "jon bob.com" (mit einem Zeilenumbruch im E-Dress)
intrepidis
4
@ChrisNash verwendet dann einen anderen Platzhalter (z. B. "|", "~" oder mehrere Zeichen, "! #!"). Siehe diese Antwort unten: stackoverflow.com/a/31179/179311 .
Bradlis7
1
"CONCAT (CHAR (13), CHAR (10))" ("\ r \ n") wäre besser für die Windows-Umgebung, was meiner Meinung nach
d.popov
12

Ich bin hierher gekommen, weil ich befürchtet hatte, dass in C # -Strings angegebene cr-lfs in den Abfrageantworten von SQl Server Management Studio nicht angezeigt werden.

Es stellt sich heraus, dass sie da sind, aber nicht angezeigt werden.

Verwenden Sie die print-Anweisung wie folgt, um die cr-lfs zu "sehen":

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

Hier ist eine C # -Funktion, die einem vorhandenen Text-Blob, der durch CRLFs begrenzt ist, eine Textzeile voranstellt und einen für INSERToder UPDATEOperationen geeigneten T-SQL-Ausdruck zurückgibt . Es enthält einige unserer proprietären Fehlerbehandlungen, aber wenn Sie diese herausreißen, kann es hilfreich sein - ich hoffe es.

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

ich würde sagen

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

oder

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

Das ist immer cool, denn wenn Sie exportierte Listen von beispielsweise Oracle erhalten, erhalten Sie Datensätze, die mehrere Zeilen umfassen, was wiederum beispielsweise für Lebenslaufdateien interessant sein kann. Seien Sie also vorsichtig.

Wie auch immer, Robs Antwort ist gut, aber ich würde empfehlen, etwas anderes als @ zu verwenden, ein paar mehr zu versuchen, wie §§ @@ §§ oder so, damit es eine Chance für eine Einzigartigkeit gibt. (Denken Sie jedoch an die Länge des Felds varchar/ nvarchar, in das Sie einfügen.)

neslekkiM
quelle
3

Alle diese Optionen funktionieren abhängig von Ihrer Situation, aber wenn Sie SSMS verwenden , sehen Sie möglicherweise keine davon (wie in einigen Kommentaren erwähnt, versteckt SSMS CR / LFs).

Aktivieren Sie diese Einstellung, anstatt sich selbst um die Kurve zu fahren

Tools | Options

welches die ersetzen wird

Trubs
quelle