Cách chèn ngắt dòng trong chuỗi VARCHAR / NVARCHAR của SQL Server


562

Tôi không thấy bất kỳ câu hỏi tương tự nào được hỏi về chủ đề này và tôi đã phải nghiên cứu vấn đề này cho một cái gì đó tôi đang làm việc ngay bây giờ. Nghĩ rằng tôi sẽ đăng câu trả lời cho nó trong trường hợp bất cứ ai khác có cùng câu hỏi.


8
Để kiểm tra đầu ra của bạn, nếu sử dụng SSMS, hãy đảm bảo tùy chọn Giữ lại CR / LF khi sao chép hoặc lưu được kiểm tra, nếu không tất cả các kết quả đã dán sẽ làm mất nguồn cấp dữ liệu. Bạn tìm thấy điều này ở cài đặt, kết quả truy vấn, máy chủ sql, kết quả vào lưới.
Stefanos Zilellis

1
@StefanosZilellis và đảm bảo mở một cửa sổ truy vấn mới để các thay đổi cài đặt có hiệu lực.
Don Cheadle

Câu trả lời:


597

char(13)CR. Đối với các CRLFngắt dòng kiểu DOS- / Windows , bạn muốn char(13)+char(10), như:

'This is line 1.' + CHAR(13)+CHAR(10) + 'This is line 2.'

28
char (13) + char (10) không hoạt động với tôi trong windows. Tôi vừa sử dụng char (10)
nima

6
@Nima: Một số ứng dụng sẽ sử dụng một hoặc cả hai hoặc cả hai để hiển thị một dòng mới, tuy nhiên nhiều ứng dụng bạn có thể xuất văn bản này sẽ yêu cầu cả hai xuất hiện liên tiếp để biểu thị một dòng mới. Tôi thấy an toàn khi sử dụng cả hai. Bạn có thể liệt kê ở đây những ứng dụng nào mà nó không hoạt động. Tôi thích bản thân các giá trị thập lục phân CHAR (0x0D) + CHAR (0x0A), nhưng với từng giá trị riêng của chúng.
MikeTeeVee

2
Tôi đã sử dụng phương pháp này thành công, nhưng gặp phải một vấn đề với nó: một khi bạn có nhiều hơn khoảng 480 +, SQL Server sẽ bắt đầu phàn nàn rằng truy vấn của bạn quá sâu. Thay vào đó, giải pháp của tôi là sử dụng câu trả lời của Rob Cooper, nhưng với mã thông báo dài hơn và tối nghĩa hơn nhiều.
Marcus Downing

5
Cung cấp \ r \ n có nghĩa là thừa nhận rằng các biểu thức chính quy tồn tại và có những người dùng có khả năng hiểu và sử dụng chúng.
wwmbes

10
@HBlackorby \ r và \ n có trước Java-mọi thứ trong nhiều thập kỷ với việc sử dụng chúng trong C; và là tiêu chuẩn trong Python, PHP, Ruby, C ++, C #, v.v ...
Uueerdo

286

Tôi tìm thấy câu trả lời ở đây: http://blog.sqlauthority.com/2007/08/22/sql-server-t-sql-script-to-insert-carriage-return-and-new-line-feed-in- mã /

Bạn chỉ cần nối chuỗi và chèn một CHAR(13)nơi bạn muốn ngắt dòng.

Thí dụ:

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

Điều này in ra như sau:

Đây là dòng 1.
Đây là dòng 2.


11
CẬP NHẬT: quên nó đi. Nó chèn tốt. Đó là studio quản lý thay thế các tab và dòng mới bằng khoảng trắng để hiển thị
Daniel Dolz

12
Có vẻ như bạn cần sử dụng PRINT @text thay vì CHỌN để có kết quả này.
QMaster

3
BTW: Bạn cũng có thể sử dụng NCHAR(0x1234)để có được một ký tự unicode. Không cần thiết để chèn ngắt dòng, nhưng có thể có ích nếu người ta phải chèn / tìm kiếm các ký tự unicode.
Paul Groke

3
Trong SQL Server 2016, tôi chỉ thấy nó in hai dòng nếu tôi sử dụng printthay vì select, chẳng hạn như:DECLARE @text NVARCHAR(100); SET @text = 'This is line 1.' + CHAR(13) + 'This is line 2.'; print @text;
devinbost

7
Để kiểm tra đầu ra của bạn, nếu sử dụng SSMS, hãy đảm bảo tùy chọn Giữ lại CR / LF khi sao chép hoặc lưu được kiểm tra, nếu không tất cả các kết quả đã dán sẽ làm mất nguồn cấp dữ liệu. Bạn tìm thấy điều này ở cài đặt, kết quả truy vấn, máy chủ sql, kết quả vào lưới.
Don Cheadle

81

Một cách khác để làm điều này là như vậy:

INSERT CRLF SELECT 'fox 
jumped'

Đó là, chỉ cần chèn một ngắt dòng trong truy vấn của bạn trong khi viết nó sẽ thêm ngắt giống như vào cơ sở dữ liệu. Điều này hoạt động trong phòng quản lý máy chủ SQL và Phân tích truy vấn. Tôi tin rằng điều này cũng sẽ hoạt động trong C # nếu bạn sử dụng dấu @ trên chuỗi.

string str = @"INSERT CRLF SELECT 'fox 
    jumped'"

14
Nói cách khác, cú pháp của ngôn ngữ SQL chỉ đơn giản cho phép các nguồn cấp dữ liệu thô trong chuỗi ký tự. Nó hoạt động theo cách này trong tất cả các công cụ tôi đã thử (SQL Server, Oracle, MySQL, PostgreSQL và SQLite).
Álvaro González

đôi khi điều này ngẫu nhiên thoát khỏi hoạt động nếu bạn sử dụng nó trong các thủ tục được lưu trữ
DaFi4

25

Chạy cái này trong SSMS, nó cho thấy cách ngắt dòng trong chính SQL trở thành một phần của các giá trị chuỗi trải dài các dòng:

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

Kết quả:
Dòng 1
Dòng 2
Dòng 3

Bao lâu là một nguồn cấp dữ liệu trống?
2

Các giá trị ASCII là gì?
13
10

Hoặc nếu bạn muốn chỉ định chuỗi của mình trên một dòng (gần như!) Bạn có thể sử dụng REPLACE()như thế này (tùy chọn sử dụng CHAR(13)+CHAR(10)làm thay thế):

PRINT REPLACE('Line 1`Line 2`Line 3','`','
')

16

Theo dõi Google ...

Lấy mã từ trang 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))

Có vẻ như điều đó có thể được thực hiện bằng cách thay thế trình giữ chỗ bằng CHAR (13)

Câu hỏi hay, không bao giờ tự làm :)


4
Nhưng nếu văn bản có một địa chỉ email trong đó? "jon@bob.com" trở thành "jon bob.com" (với một dòng mới trong trang phục điện tử)
intrepidis

4
@ChrisNash sau đó sử dụng một trình giữ chỗ khác (ví dụ: "|", "~" hoặc nhiều ký tự, "! #!"). Xem câu trả lời dưới đây: stackoverflow.com/a/31179/179311 .
bradlis7

1
"CONCAT (CHAR (13), CHAR (10))" ("\ r \ n") sẽ tốt hơn cho môi trường windows, mà tôi giả sử là trường hợp (SQL Server) cs.toronto.edu/~krueger/csc209h/ tut / line-endings.html
d.popov

12

Tôi đã đến đây vì tôi lo ngại rằng cr-lfs mà tôi đã chỉ định trong chuỗi C # không được hiển thị trong các phản hồi truy vấn của SQl Server Management Studio.

Hóa ra, họ ở đó, nhưng không được hiển thị.

Để "xem" cr-lfs, hãy sử dụng câu lệnh in như:

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

4

Đây là hàm C # bổ sung một dòng văn bản cho một blob văn bản hiện có, được phân định bằng CRLF và trả về một biểu thức T-SQL phù hợp cho INSERThoặc UPDATEhoạt động. Nó có một số xử lý lỗi độc quyền của chúng tôi trong đó, nhưng một khi bạn tách nó ra, nó có thể hữu ích - tôi hy vọng vậy.

/// <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("");
    }
}

4

tôi sẽ nói

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

hoặc là

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

3

Điều này luôn tuyệt vời, bởi vì khi bạn nhận được danh sách xuất từ ​​Oracle, sau đó bạn nhận được các bản ghi trải dài trên một số dòng, điều này có thể thú vị đối với các tệp cvs, vì vậy hãy cẩn thận.

Dù sao đi nữa, câu trả lời của Rob là tốt, nhưng tôi sẽ khuyên bạn nên sử dụng một cái gì đó khác ngoài @, thử thêm một vài thứ, như § § @@ § § hoặc một cái gì đó, vì vậy nó sẽ có cơ hội cho một sự độc đáo. (Tuy nhiên, hãy nhớ độ dài của varchar/ nvarchartrường bạn đang chèn vào ..)


3

Tất cả các tùy chọn này hoạt động tùy thuộc vào tình huống của bạn, nhưng bạn có thể không thấy bất kỳ tùy chọn nào trong số chúng hoạt động nếu bạn đang sử dụng SSMS (như đã đề cập trong một số nhận xét SSMS ẩn CR / LFs)

Vì vậy, thay vì tự lái xe quanh khúc quanh, hãy kiểm tra cài đặt này trong

Tools | Options

cái nào sẽ thay thế

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.