2010-03-25 1 views
4

У меня есть CSV дамп от другой БД, которая выглядит следующим образом (ID, имя, примечание):Как навалом вставить из CSV, когда некоторые поля имеют новый символ строки?

1001,John Smith,15 Main Street
1002,Jane Smith,"2010 Rockliffe Dr.
Pleasantville, IL
USA"
1003,Bill Karr,2820 West Ave.

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

Я использую этот код, чтобы импортировать CSV в моей таблице:

BULK INSERT CSVTest 
FROM 'c:\csvfile.csv' 
WITH 
(
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = '\n' 
) 

SQL Server 2005 основная вставка не может понять, что возврат каретки внутри кавычек не грести терминаторы.
Как победить?


UPDATE:
Похоже, единственный способ сохранить разрывы строк внутри поля использовать другой разделитель строк. Итак, я хочу отметить все разрывы строк, разделив строки, поставив перед ними трубку. Как я могу изменить свой CSV, чтобы выглядеть так?

1001,John Smith,15 Main Street|
1002,Jane Smith,"2010 Rockliffe Dr.
Pleasantville, IL
USA"|
1003,Bill Karr,2820 West Ave.|

ответ

0

OK, вот небольшая Java программа, которую я в конечном итоге писать, чтобы решить эту проблему.
Комментарии, исправления и оптимизация приветствуются.

import java.io.*; 

public class PreBulkInsert 
{ 
    public static void main(String[] args) 
    { 
     if (args.length < 3) 
     { 
      System.out.println ("Usage:"); 
      System.out.println (" java PreBulkInsert input_file output_file separator_character"); 
      System.exit(0); 
     } 

     try 
     { 
      boolean firstQuoteFound = false; 
      int fromIndex; 
      int lineCounter = 0; 
      String str; 

      BufferedReader in = new BufferedReader(new FileReader(args[0])); 
      BufferedWriter out = new BufferedWriter(new FileWriter(args[1])); 
      String newRowSeparator = args[2]; 

      while ((str = in.readLine()) != null) 
      { 
       fromIndex = -1; 
       do 
       { 
        fromIndex = str.indexOf('"', fromIndex + 1); 
        if (fromIndex > -1) 
         firstQuoteFound = !firstQuoteFound; 
       } while (fromIndex > -1); 

       if (!firstQuoteFound) 
        out.write(str + newRowSeparator + "\r\n"); 
       else 
        out.write(str + "\r\n"); 
       lineCounter++; 
      } 
      out.close(); 
      in.close(); 
      System.out.println("Done! Total of " + lineCounter + " lines were processed."); 
     } 
     catch (IOException e) 
     { 
      System.out.println(e.getMessage()); 
      System.exit(1); 
     }  
    } 
} 
0

Согласно источнику всех знаний (Wikipedia), csv использует новые линии для разделения записей. Так что у вас есть недопустимый csv.

Мое предложение состоит в том, что вы пишете программу perl для обработки вашего файла и добавляете каждую запись в db.

Если вы не человек perl, вы можете использовать сайт программирования или посмотреть, будет ли какой-то человек SO писать секцию разбора программы для вас.

Добавлено:

Возможное решение

Поскольку OP утверждает, что он может изменить входной файл, я изменил бы все новые линии, которые не следуют ", чтобы быть зарезервированным последовательность голец , например, XXX

Это может быть автоматизирован замена во многих редакторах. в Windows UltraEdit включает в себя регулярное выражение поиска/замены функциональных возможностей

затем импортировать в DBMS, так как вы будете п o длиннее встроенные новые строки.

Затем используйте SQL Replace, чтобы изменить появление XXX на новые строки.

+2

также из источника всех знаний: «Поля со встроенными разрывами строк должны быть заключены в символы двойной кавычки», поэтому входной файл действителен. – Jimmy

+0

Не вариант. Это должен быть сценарий SQL, который будет выполняться где-то еще кем-то другим. Тем не менее, я могу настроить CSV-файл в любом случае в редакторе. –

1

Массовые операции на SQL Server не поддерживают CSV, даже если они могут импортировать их, если файлы тщательно отформатированы. Мое предложение состояло в том, чтобы заключить все значения полей в кавычки. BULK INSERT может затем разрешить возврат каретки в значение поля. Если это не так, то следующим решением может быть пакет служб Integration Services.

См. Preparing Data for Bulk Export or Import для получения дополнительной информации.

0

Вы не можете импортировать это, если CSV не находится в допустимом формате. Таким образом, вам нужно либо исправить дамп, либо вручную, используя поиск & заменить исправление нежелательных новых символов строки.

+0

Дело в том, что мне нужно сохранить эти новые строковые символы в поле примечаний. Даже если я смогу удалить их, CSV огромен, и я не могу полностью автоматизировать его в редакторе. –

+0

Попробуйте дамп без добавления поля заметок, затем сделайте еще один дамп только с полем нот, но на этот раз посмотрите, можете ли вы заменить ненужные символы. Также вам придется импортировать дважды, так как у вас есть две свалки. – SoftwareGeek

+0

Если вы имеете в виду дамп из базы данных, я не могу этого сделать: CSV предоставляется мне как есть. –

0

Если у вас есть контроль над содержимым файла CSV, можно заменить в полевых строках (CRLF) с не-LineBreak характером (возможно, просто CR или LF), а затем запустить скрипт после импорта в замените их на CRLF.

Вот как справляются с этой проблемой продукты MS Office (Excel, Access).

+0

Но как я могу надежно различать разрывы строк в строке и разрывы строк? –

+0

@ z-boss - возможно, я неправильно понял ваш вопрос - я предположил, что вы контролируете производство CSV-файла. –

1

вы можете массировать эти разрывы строк в одну строку со сценарием, например, вы можете использовать GNU sed для удаления разрывов строк. например

$ more file 
1001,John Smith,15 Main Street 
1002,Jane Smith,"2010 Rockliffe Dr. 
Pleasantville, IL 
USA" 
1003,Bill Karr,"2820 
West Ave" 

$ sed '/"/!s/$/|/;/.*\".*[^"]$/{ :a;N };/"$/ { s/$/|/ }' file 
1001,John Smith,15 Main Street| 
1002,Jane Smith,"2010 Rockliffe Dr. 
Pleasantville, IL 
USA"| 
1003,Bill Karr,"2820 
West Ave"| 

то вы можете навалом вставить.

Edit:

Сохранить: /"/!s/$/|/;/.*\".*[^"]$/{ :a;N };/"$/ { s/$/|/ } в файле, скажем myformat.sed. то сделать это в командной строке

c:\test> sed.exe -f myformat.sed myfile

+0

Мне нужно сохранить эти разрывы в поле. Возможно ли, если sed будет добавлять все не в полевые разрывы линии с символом трубы? Таким образом, я использовал бы '| \ n' в качестве разделителя строк для объемной вставки, и он будет работать. –

+0

Я не понимаю. вы имеете в виду что-то вроде этого: '2010 | Rockliffe Dr | Pleasantville | IL USA'? если нет, вы должны, вероятно, показать свой желаемый результат в своем вопросе – ghostdog74

+0

Я обновил свой вопрос. –

Смежные вопросы