Дополнительная обратная косая черта \ когда SELECT ... INTO OUTFILE ... в MySQL - PullRequest
10 голосов
/ 11 марта 2011

Итак, я пытаюсь экспортировать таблицу MySQL в CSV. Я использую этот запрос:

SELECT * FROM business WHERE id > 0 AND id <= 20000 INTO OUTFILE "business.csv"
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY "\n";

Это выводится примерно так:

http://postimage.org/image/2ghyenh5w/full/

Проблема в том, что всегда есть дополнительная обратная косая черта \, где есть символ новой строки, такой как в поле адреса.

Однако в CSV, экспортированном из phpMyAdmin, его нет:

http://postimage.org/image/2gi026tno/full/

Есть ли способ заставить SELECT ... OUTFILE ... сделать то же самое?

Таблица, с которой я имею дело, содержит 20 миллионов записей, phpMyAdmin может обработать только около 500 000 записей для каждого действия экспорта - или он будет пустым или сервер mysql исчезнет и т. Д.

Ответы [ 7 ]

5 голосов
/ 21 мая 2013

Похоже, что для экспорта MySQL невозможно правильно экспортировать и переводы строк и кавычки.

При экспорте MySQL автоматически экранирует оба

  • Разделители полей и
  • Разделители строк

По умолчанию escape-символ представляет собой обратную косую черту. Вы можете изменить это, добавив ESCAPED BY '' к вашему запросу.

К сожалению, в "нормальном" (совместимом с Excel) CSV-файле вам, вероятно, нужны разные кодировки для перевода строки и кавычек. В частности, вы хотите, чтобы переводы строк не были удалены, а кавычки были удвоены

например. Если значение содержит символ новой строки, например:

Это строка 1
И это «Строка 2», которая содержит кавычки

должно стать

"Это строка 1
А это "" Строка 2 "", которая содержит кавычки "

Решением, которое я нашел, было предварительное экранирование кавычек и добавление ESCAPED BY '' (пустая строка) к моему запросу.

SELECT REPLACE(field1, '"', '""'),  
       REPLACE(field2, '"', '""'),  
       ...  
FROM ...  
WHERE ...  
INTO OUTFILE '/someFile.csv'  
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY ''  
LINES TERMINATED BY '\n'
5 голосов
/ 11 марта 2011

Попробуйте:

SELECT * FROM business WHERE id > 0 AND id <= 20000 INTO OUTFILE "business.csv"
fields terminated by ',' OPTIONALLY ENCLOSED BY '"' escaped by '"' 
LINES TERMINATED BY '\n';

Я думаю, проблема в том, что MySQL пытается экранировать символ новой строки ('\ n') в ваших текстовых полях, потому что это ваш терминатор строки.

ПОЛЕ ESCAPED BY контролирует, как писать специальные символы.Если символ FIELDS ESCAPED BY не пуст, он используется в качестве префикса, который предшествует следующим символам при выводе:

Символ FIELDS ESCAPED BY

FIELDS [OPTIONALLY] ENCLOSED BY символ

Первым символом полей, ПРЕКРАЩАЕМЫХ ПО и ЛИНИИ, ПРЕКРАЩЕННЫМИ значениями

ASCII NUL (байт с нулевым значением; то, что фактически записывается после escape-символа, это ASCII «0», а не нользначение в байтах)

( MySQL )

Я не очень понимаю, почему он делает то, что делает в вашем случае, но я смог что-то получитькак на моем Mac, и запрос выше, похоже, исправил вывод в моем случае.

Надеюсь, это поможет!

1 голос
/ 12 августа 2011

У меня была такая же проблема, и я обнаружил (после импорта файла csv в электронную таблицу), что в некоторых полях varchar в таблице MySQL были разрывы строк. После удаления разрывов строк экспорт работал корректно.

0 голосов
/ 11 октября 2018
SELECT * FROM business WHERE id > 0 AND id <= 20000 INTO OUTFILE "business.csv"fields terminated by ',' 
OPTIONALLY ENCLOSED BY '"' ESCAPED BY '' LINES TERMINATED BY '\n';

Во-первых, не ставьте '"" в качестве escape, это изменит ваш контент.

Во-вторых, если вы используете этот запрос в следующей строке, вам нужно также удалить дополнительный '\n' добавить строку из нескольких строк.

mysql -e "SELECT * FROM business WHERE id > 0 AND id <= 20000 INTO OUTFILE "business.csv"
fields terminated by ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '' 
LINES TERMINATED BY '\n';"
0 голосов
/ 17 сентября 2018

Я решил это, указав \r\n в качестве ограничителя строки, а не \n:

SELECT * FROM business WHERE id > 0 AND id <= 20000
INTO OUTFILE "business.csv"
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
ESCAPED BY '\'
LINES TERMINATED BY '\r\n';

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

Удивительно, но это отлично работало на Linux для моих целей - импорт с использованием League \ Csv (PHP). Я предполагаю, что любое программное обеспечение будет импортировать ваши сгенерированные CSV, должно быть достаточно умным, чтобы различать между \n и \r\n для разрывов строк.

0 голосов
/ 14 августа 2017

Получил ответ здесь https://bugs.mysql.com/bug.php?id=46434

Основные моменты:
1. INTO OUTFILE предназначен для получения результатов, готовых к загрузке с помощью LOAD DATA
2. По умолчанию ESCAPED BY равен '\'
3. Чтобы отключить экранирование, используйте ESCAPED BY ''

0 голосов
/ 26 августа 2016

Попробуйте это:

SELECT * FROM business WHERE id > 0 AND id <= 20000 INTO OUTFILE "business.csv"
FIELDS TERMINATED BY  ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\' 
LINES TERMINATED BY '\n';

Я понял, что использование escaped by '\' делает удаляет обратную косую черту в экспортированных результатах.

...