Як вставити розрив рядка в рядок VARCHAR / NVARCHAR SQL Server


561

Я не бачив жодних подібних запитань на цю тему, і мені довелося дослідити це над тим, над чим я зараз працюю. Думав, я надішлю відповідь на це у випадку, якщо у когось іншого виникне те саме питання.


8
Щоб перевірити вихід, якщо ви використовуєте SSMS, переконайтеся, що встановлено прапорець Затримати CR / LF при копіюванні чи збереженні, інакше всі вставлені результати втратять канал каналу. Ви знаходите це в налаштуваннях, результатах запитів, сервері sql, результатах в сітці.
Стефанос Зілеліс

1
@StefanosZilellis і переконайтеся, що відкрийте нове вікно запитів, щоб зміни налаштування набули чинності.
Дон

Відповіді:


595

char(13)є CR. Для CRLFрядків у стилі DOS / Windows вам потрібно char(13)+char(10):

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

28
char (13) + char (10) не працював для мене у Windows. Я щойно використав char (10)
німа

6
@Nima: Деякі програми використовуватимуть той чи інший або обидва для показу нового рядка, проте для багатьох програм, для яких ви можете вивести цей текст, потрібно, щоб обидва з'являлися послідовно для позначення нового рядка. Я вважаю безпечним використання обох. Тут ви можете перелічити, які програми не працюють. Я віддаю перевагу значенням CHAR (0x0D) + CHAR (0x0A) шістнадцятковим самим, але кожному своєму.
MikeTeeVee

2
Я використовував цей метод успішно, але зіткнувся з проблемою: як тільки у вас буде більше 480 +, SQL Server почне скаржитися, що ваш запит занадто глибоко вкладений. Моє рішення було замість цього використовувати відповідь Роб Купер, але з набагато довшим та більш незрозумілим ознакою.
Маркус Даунінг

5
Надання \ r \ n означатиме підтвердження того, що регулярні вирази існують і що є користувачі, здатні їх розуміти та використовувати.
wwmbes

10
@HBlackorby \ r і \ n передували Java-що-небудь десятиліттям із їх використанням у C; і є стандартними для Python, PHP, Ruby, C ++, C # тощо ...
Uueerdo

285

Відповідь я знайшов тут: http://blog.sqlauthority.com/2007/08/22/sql-server-t-sql-script-to-insert-carriage-return-and-new-line-feed-in- код /

Ви просто з'єднали рядок і вставили CHAR(13)туди, де ви хочете розрив рядка.

Приклад:

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

Це видає таке:

Це рядок 1.
Це рядок 2.


11
ОНОВЛЕННЯ: забудьте. Він вставляється просто чудово. Це студія управління тією, яка замінює вкладки та нові рядки пробілами для наочності
Даніель Долз

12
Здається, вам потрібно використовувати PRINT @text, а не SELECT, щоб отримати цей результат.
QMaster

3
BTW: Ви також можете використовувати NCHAR(0x1234)символ Unicode. Не потрібно для вставки розривів рядків, але може стати в нагоді, якщо потрібно вставити / шукати символи unicode.
Пол Грок

3
У SQL Server 2016 я бачу, як він надрукує два рядки, якщо я використовую printзамість цього select, наприклад:DECLARE @text NVARCHAR(100); SET @text = 'This is line 1.' + CHAR(13) + 'This is line 2.'; print @text;
devinbost

7
Щоб перевірити вихід, якщо ви використовуєте SSMS, переконайтеся, що встановлено прапорець Утримувати CR / LF при копіюванні чи збереженні, інакше всі вставлені результати втратять канал каналу. Ви знаходите це в налаштуваннях, результатах запитів, сервері sql, результатах в сітці.
Дон

81

Ще один спосіб зробити це:

INSERT CRLF SELECT 'fox 
jumped'

Тобто, просто вставити розрив рядка у запит під час його запису додасть подібний перерву до бази даних. Це працює в студії управління SQL-сервером і аналізаторі запитів. Я вважаю, що це також спрацює в C #, якщо ви будете використовувати знак @ на рядках.

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

14
Іншими словами, синтаксис мови SQL просто дозволяє подавати необмежену стрічку рядків у рядкових літералах. Це працює таким чином у всіх двигунах, які я пробував (SQL Server, Oracle, MySQL, PostgreSQL і SQLite).
Альваро Гонсалес

іноді це випадковим чином припиняє роботу, якщо ви використовуєте його в збережених процедурах
DaFi4

25

Запустивши це в SSMS, він показує, як розриви рядків у самому SQL стають частиною рядкових значень, що охоплюють рядки:

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

Результат:
Рядок 1
Рядок 2
Рядок 3

Як довго триває подача порожнього рядка?
2

Що таке значення ASCII?
13
10

Або якщо ви бажаєте вказати рядок в одному рядку (майже!), Ви можете використовувати REPLACE()такий (як варіант CHAR(13)+CHAR(10), замість цього):

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

16

Слідом за Google ...

Беручи код з веб-сайту:

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

Схоже, це можна зробити, замінивши заповнювач CHAR (13)

Добре запитання, я ніколи цього не робив сам :)


4
Але якщо в тексті є адреса електронної пошти? "jon@bob.com" стає "jon bob.com" (з новою лінією в електронній сукні)
intrepidis

4
@ChrisNash тоді використовуйте інший заповнювач (наприклад, "|", "~" або кілька символів, "! #!"). Дивіться цю відповідь нижче: stackoverflow.com/a/31179/179311 .
bradlis7

1
"CONCAT (CHAR (13), CHAR (10))" "(" \ r \ n ") буде кращим для середовища Windows, що, мабуть, так і
d.popov

12

Я потрапив сюди, тому що мене турбувало, що cr-lfs, які я вказав у рядках C #, не відображалися у відповідях на запити студії управління сервісом SQl.

Виявляється, вони там є, але не відображаються.

Щоб "побачити" cr-lfs, використовуйте оператор print, наприклад:

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

4

Ось функція С # , яка підставляє текстова рядок в існуючому тексті згусток, обмежена CRLFs, і повертає вираз T-SQL підходить для INSERTабо UPDATEоперації. У ній є деякі наші власні помилки, але коли ви виправите це, це може бути корисним - я сподіваюся, що так.

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

Я б сказав

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

або

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

3

Це завжди круто, адже коли ви отримуєте експортовані списки з, скажімо, Oracle, тоді ви отримуєте записи, що охоплюють декілька рядків, що, в свою чергу, може бути цікавим, наприклад, для файлів cvs, тому будьте обачні.

Так чи інакше, відповідь Роб хороша, але я б радив використовувати щось інше, ніж @, спробуйте ще декілька, наприклад, §§ @@ §§ чи щось таке, тож у нього з’явиться шанс на якусь унікальність. (Але все ж пам’ятайте довжину поля varchar/, nvarcharяке ви вставляєте в ..)


3

Усі ці параметри працюють залежно від вашої ситуації, але ви, можливо, не бачите жодного з них, якщо ви використовуєте SSMS (як зазначено в деяких коментарях. SSMS приховує CR / LF)

Тому замість того, щоб їхати за поворотом, перевірте цю установку

Tools | Options

який замінить

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.