Comment insérer un saut de ligne dans une chaîne VARCHAR / NVARCHAR SQL Server

562

Je n'ai pas vu de questions similaires posées sur ce sujet, et j'ai dû rechercher ceci pour quelque chose sur lequel je travaille en ce moment. J'ai pensé que je posterais la réponse pour le cas où quelqu'un d'autre aurait la même question.

Mark Struzinski
la source
8
Pour tester votre sortie, si vous utilisez SSMS, assurez-vous que l'option Conserver CR / LF lors de la copie ou de l'enregistrement est cochée, sinon tous les résultats collés perdront le saut de ligne. Vous le trouverez dans les paramètres, les résultats de la requête, le serveur SQL, les résultats dans la grille.
Stefanos Zilellis
1
@StefanosZilellis et assurez-vous d'ouvrir une nouvelle fenêtre de requête pour que les changements de paramètres prennent effet.
Don Cheadle

Réponses:

597

char(13)est CR. Pour les sauts de ligne de style DOS / Windows CRLF, vous voulez char(13)+char(10), comme:

'This is line 1.' + CHAR(13)+CHAR(10) + 'This is line 2.'
Sören Kuklau
la source
28
char (13) + char (10) ne fonctionnait pas pour moi dans Windows. Je viens d'utiliser char (10)
nima
6
@Nima: Certaines applications utiliseront l'une ou l'autre ou les deux pour afficher une nouvelle ligne, mais de nombreuses applications pour lesquelles vous pouvez afficher ce texte nécessiteront que les deux apparaissent successivement pour signifier une nouvelle ligne. Je trouve sûr d'utiliser les deux. Vous pouvez répertorier ici les applications pour lesquelles cela ne fonctionne pas. Je préfère moi-même les valeurs hexadécimales CHAR (0x0D) + CHAR (0x0A), mais à chacune la leur.
MikeTeeVee
2
J'ai utilisé cette méthode avec succès, mais j'ai rencontré un problème: une fois que vous en avez plus de 480 environ +, SQL Server commencera à se plaindre que votre requête est trop profondément imbriquée. Ma solution était plutôt d'utiliser la réponse de Rob Cooper à la place, mais avec un jeton beaucoup plus long et plus obscur.
Marcus Downing
5
Fournir \ r \ n signifierait reconnaître qu'il existe des expressions régulières et qu'il existe des utilisateurs capables de les comprendre et de les utiliser.
wwmbes
10
@HBlackorby \ r et \ n sont antérieurs à Java-n'importe quoi de plusieurs décennies avec leur utilisation en C; et sont standard en Python, PHP, Ruby, C ++, C #, etc ...
Uueerdo
286

J'ai trouvé la réponse ici: http://blog.sqlauthority.com/2007/08/22/sql-server-t-sql-script-to-insert-carriage-return-and-new-line-feed-in- code/

Vous venez de concaténer la chaîne et d'insérer un CHAR(13)où vous voulez que votre saut de ligne.

Exemple:

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

Cela imprime ce qui suit:

C'est la ligne 1.
C'est la ligne 2.

Mark Struzinski
la source
11
MISE À JOUR: oubliez ça. Il insère très bien. C'est le studio de gestion celui qui remplace les onglets et les nouvelles lignes par des espaces pour la visibilité
Daniel Dolz
12
Il semble que vous ayez besoin d'utiliser PRINT @text plutôt SELECT pour obtenir ce résultat.
QMaster
3
BTW: Vous pouvez également utiliser NCHAR(0x1234)pour obtenir un caractère unicode. Pas nécessaire pour insérer des sauts de ligne, mais peut être utile si l'on doit insérer / rechercher des caractères Unicode.
Paul Groke
3
Dans SQL Server 2016, je ne le vois imprimer les deux lignes que si j'utilise à la printplace de select, comme:DECLARE @text NVARCHAR(100); SET @text = 'This is line 1.' + CHAR(13) + 'This is line 2.'; print @text;
devinbost
7
Pour tester votre sortie, si vous utilisez SSMS, assurez-vous que l'option Conserver CR / LF lors de la copie ou de l'enregistrement est cochée, sinon tous les résultats collés perdront le saut de ligne. Vous le trouverez dans les paramètres, les résultats de la requête, le serveur SQL, les résultats dans la grille.
Don Cheadle
81

Une autre façon de procéder est en tant que telle:

INSERT CRLF SELECT 'fox 
jumped'

Autrement dit, l'insertion d'un saut de ligne dans votre requête lors de son écriture ajoutera le même saut à la base de données. Cela fonctionne dans SQL Server Management Studio et Query Analyzer. Je crois que cela fonctionnera également en C # si vous utilisez le signe @ sur les chaînes.

string str = @"INSERT CRLF SELECT 'fox 
    jumped'"
Frank V
la source
14
En d'autres termes, la syntaxe du langage SQL autorise simplement les sauts de ligne bruts dans les chaînes de caractères littéraux. Cela fonctionne de cette façon dans tous les moteurs que j'ai essayés (SQL Server, Oracle, MySQL, PostgreSQL et SQLite).
Álvaro González
parfois, cela cesse de fonctionner aléatoirement si vous l'utilisez dans des procédures stockées
DaFi4
25

Exécutez ceci dans SSMS, il montre comment les sauts de ligne dans le SQL lui-même deviennent une partie des valeurs de chaîne qui s'étendent sur les lignes:

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

Résultat:
ligne 1
ligne 2
ligne 3

Quelle est la durée d'un saut de ligne vierge?
2

Quelles sont les valeurs ASCII?
13
10

Ou si vous préférez spécifier votre chaîne sur une seule ligne (presque!), Vous pouvez utiliser REPLACE()comme ceci (éventuellement utiliser CHAR(13)+CHAR(10)comme remplacement):

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

Suivre un Google ...

Prendre le code du site 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))

Il semble que cela puisse être fait en remplaçant un espace réservé par CHAR (13)

Bonne question, je ne l'ai jamais fait moi-même :)

Rob Cooper
la source
4
Mais si le texte contient une adresse e-mail? "[email protected]" devient "jon bob.com" (avec une nouvelle ligne dans l'e-dress)
intrepidis
4
@ChrisNash utilise alors un espace réservé différent (par exemple "|", "~" ou plusieurs caractères, "! #!"). Voir cette réponse ci-dessous: stackoverflow.com/a/31179/179311 .
bradlis7
1
"CONCAT (CHAR (13), CHAR (10))" ("\ r \ n") serait mieux pour l'environnement Windows, ce qui, je suppose, est le cas (SQL Server) cs.toronto.edu/~krueger/csc209h/ tut / line-endings.html
d.popov
12

Je suis arrivé ici parce que je craignais que les cr-lfs que j'ai spécifiés dans les chaînes C # ne soient pas affichés dans les réponses aux requêtes SQl Server Management Studio.

Il s'avère qu'ils sont là, mais ne sont pas affichés.

Pour "voir" les cr-lfs, utilisez l'instruction print comme:

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

Voici une fonction C # qui ajoute une ligne de texte à un blob de texte existant, délimité par des CRLF, et renvoie une expression T-SQL appropriée pour INSERTou des UPDATEopérations. Il contient une partie de notre gestion d'erreurs propriétaire, mais une fois que vous l'avez extraite, cela peut être utile - je l'espère.

/// <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
la source
4

Je dirais

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
la source
3

C'est toujours cool, car lorsque vous obtenez des listes exportées depuis, par exemple Oracle, vous obtenez des enregistrements sur plusieurs lignes, ce qui peut être intéressant pour, disons, les fichiers cvs, alors méfiez-vous.

Quoi qu'il en soit, la réponse de Rob est bonne, mais je conseillerais d'utiliser autre chose que @, essayez-en un peu plus, comme §§ @@ §§ ou quelque chose, donc cela aura une chance d'être unique. (Mais n'oubliez pas la longueur du champ varchar/ dans nvarcharlequel vous insérez ..)

neslekkiM
la source
3

Toutes ces options fonctionnent selon votre situation, mais vous ne verrez peut-être aucune d'entre elles fonctionner si vous utilisez SSMS (comme mentionné dans certains commentaires SSMS cache les CR / LF)

Donc, plutôt que de vous conduire dans le virage, vérifiez ce paramètre dans

Tools | Options

qui remplacera le

Trubs
la source