Экранирование BCP \n в данных

Я использую BCP для загрузки данных с SQL Server, используя опцию запроса.

Однако я заметил, что если содержимое данных в каких-либо столбцах содержит '\n', содержимое, экспортированное из BCP, будет рассматриваться как новая строка.

Например, если данные в SQL Server:

COLUMN_1 COLUMN_2
AAA NAME\nSURNAME
BBB NAMESURNAME

Экспортируемый файл будет выглядеть так:

AAA NAME
SURNAME
BBB NAMESURNAME

Обратитесь к документу BCP, насколько я понимаю, -c не должен рассматривать \n как новую строку.

-c Выполняет операцию, используя символьный тип данных. Этот параметр не запрашивает каждое поле; он использует char в качестве типа хранения без префиксов и с \t (символ табуляции) в качестве разделителя полей и \r\n (символ новой строки) в качестве конца строки. -c не совместим с -w.

Я не уверен, что я неправильно понял.

Вот команда, которую я использую:

bcp "select [col_name] from [table_name] where [condition]" queryout test.dat -U[username] -P[password] -S[serverip.port] -c

Спасибо.


person Spacez    schedule 27.03.2020    source источник
comment
Я не вижу такого поведения с bcp "select 'hello\nworld'" queryout test.txt -S(local) -T -c... type test.txt, как и ожидалось, дает hello\nworld - не разрыв строки, а отдельные символы \ и n.   -  person AlwaysLearning    schedule 28.03.2020
comment
Для справки, я использовал C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\bcp.exe   -  person AlwaysLearning    schedule 28.03.2020
comment
Поскольку ваши данные хранятся в SQL Server, если вы запросите их, увидите ли вы на самом деле \n в данных? Или вы имеете в виду, что между значениями в столбце 2 вашего образца в первой записи есть символ новой строки? Это важное различие. Если у вас есть буквально два байта \ и n (это менее вероятно)... тогда это более загадочно. Но если вы имеете в виду, что у вас есть один байт \n символа новой строки ascii между вашими значениями внутри столбца, тогда ответ прост.   -  person jamie    schedule 30.03.2020
comment
Привет @jamie, я до сих пор не понимаю разницы между '\n' и '\' и 'n'? Как вы упомянули, способ решения этих двух случаев различен (более загадочный и простой).   -  person Spacez    schedule 31.03.2020
comment
Вы должны сначала ответить на мой предыдущий вопрос. Вы действительно видите \n при просмотре данных из SSMS? Если данные содержат управляющие символы, как вы говорите, то вы НЕ увидите данные, если не просмотрите их с помощью качественного текстового редактора и не скажете ему показывать вам управляющие символы. Эти управляющие символы НЕ печатаются. Они не существуют для человеческого глаза... \n - это просто способ передать новый управляющий символ строки. Но если вы видите два символа \ и n при просмотре данных в окне результатов запроса в SSMS, то у вас странная проблема.   -  person jamie    schedule 04.04.2020
comment
это сбивает с толку, потому что вы сказали, что у вас есть \n в ваших данных, но ниже в ответе Мартина вы сказали, что заменили \r\n (char (13) и char (10))... который находится в ваших данных? \n или \r\n?   -  person jamie    schedule 04.04.2020
comment
Спасибо за ваш ответ. Во-первых, я не использую SSMS, из-за некоторых политик компании я не могу использовать многие инструменты. Время, когда я сказал о «\ n» в своих данных, связано с использованием pyodbc (библиотека Python) и запросом их. Во-вторых, я заменял '\r' и '\n' отдельно, а не '\r\n'.   -  person Spacez    schedule 08.04.2020


Ответы (2)


Если ваши данные содержат управляющие символы новой строки или crlf, то эти символы, естественно, БУДУТ включены в копируемые данные.

Должны ли быть управляющие символы? Если это так, то оставьте их, и они будут импортированы в любое место назначения. Тот факт, что ваше текстовое представление показывает "сломанную" строку, не означает, что SQL Server не может снова принять эту строку и оставить управляющий символ спрятанным в данных (опять же, если эти управляющие символы принадлежат этому... я видел много случаях, когда они были бы).

Если символ новой строки "\n" (или любой управляющий символ в этом отношении) НЕ желателен, то это просто вопрос того, что вы прокомментировали в ответе Мартина. Просто очистите данные либо перед запросом («обновление»), либо во время запроса (как вы прокомментировали «выбрать/заменить»), либо после того, как вы скопировали данные.

В прошлом я использовал приложения «очиститель файлов», чтобы «очистить» файл от нежелательных символов (это может быть проблемой с долгоживущими данными или данными, которые прошли через различные платформы или были затронуты людьми!!! Фу! ).

person jamie    schedule 30.03.2020
comment
Интересно, есть ли возможное решение для случая, когда требуется \n, но экспортированный файл не будет использоваться SQL Server? Кроме того, как вы упомянули очиститель файлов, я пытался найти этот инструмент, но нашел только очистку для ОС. - person Spacez; 31.03.2020
comment
очиститель файлов - проприетарное приложение, каждый раз. сомневаюсь, что сможете найти. Если требуется символ новой строки, пункт назначения не имеет значения (если вы не используете собственный режим). Если вам нужен символ новой строки, просто оставьте данные как есть и не используйте замену. - person jamie; 31.03.2020

Я предполагаю, что ваш текст включает фактический управляющий символ \n, а не просто символы \ и n рядом друг с другом?

Там, где это существует, вы можете либо использовать собственный режим, либо изменить терминатор строки на что-то другое, кроме \n, чтобы он распознавал правильный шаблон.

Я бы предложил использовать собственный режим и проверить, правильно ли он повторно импортирует данные с \n на месте.

person Martin Cairney    schedule 28.03.2020
comment
Я не уверен, как определить, является ли мой текст настоящим \n или нет. Я попробую с родным режимом и снова обновлю. - person Spacez; 30.03.2020
comment
Привет Мартин. После перехода в собственный режим и повторного запуска теста я обнаружил, что многие символы не читаются, кроме английских. Я не уверен, почему родной режим дает это. Однако я попытался заменить CR LF (CHAR(13), CHAR(10)), когда SELECT в запросе. Результат кажется пригодным для использования. - person Spacez; 30.03.2020
comment
Собственные режимы отправляют данные в собственном формате SQL. Это формат, используемый SQL Server для хранения данных в собственных файлах данных. Он используется в основном для большей эффективности (меньшие размеры файлов) и может использоваться только в том случае, если источником и местом назначения является SQL Server. Однако вам не нужно использовать собственный режим для решения этой проблемы. - person jamie; 30.03.2020
comment
Тот факт, что замена управляющих символов в вашем операторе SELECT работает, указывает на то, что проблема была с этими символами в выводе. Если вам не нужно иметь возможность самостоятельно читать выходные файлы (т.е. не только используемые для экспорта/импорта), используйте собственный режим, поскольку это означает, что вам не нужно проверять наличие специальных символов в вашем тексте. @jamie - почему для решения этой проблемы не следует рассматривать собственный режим? - person Martin Cairney; 31.03.2020
comment
Потому что собственный режим не решает эту проблему. Проблема только в том, что в данных действительно ЕСТЬ управляющие символы. BCP не тот, кто ломает линию. Это любой считыватель, который OP использует для просмотра файла после выхода bcp. Что должно быть подтверждено OP, так это то, должны ли быть там управляющие символы или нет. Они вполне могут быть там, потому что они должны быть в данных. Отправка данных в собственном режиме ничего не делает для обращения к управляющим символам в данных... они все еще будут там, когда собственный файл будет восстановлен (кстати, можно восстановить только в SQL). - person jamie; 31.03.2020
comment
Использование собственного режима просто скрывает символы \n в искаженных данных собственного режима. Они все еще там, вы просто не можете легко просмотреть их в файле извлечения в собственном режиме. - person jamie; 31.03.2020
comment
Большое спасибо, Мартин и Джейми, теперь, когда я понимаю, что следует использовать в собственном режиме, я думаю, что это не будет соответствовать моим ожиданиям, поскольку я хотел бы экспортировать данные из SQL Server и читать данные с помощью Spark. Что касается беспокойства о том, что '\ n' должен быть там или нет, лично мне это не нужно (просто лучше, если это может быть), поэтому я думаю, что мне придется рассмотреть решения и поторговаться. - person Spacez; 31.03.2020