Массовый импорт SQL из CSV - PullRequest
       72

Массовый импорт SQL из CSV

23 голосов
/ 19 сентября 2008

Мне нужно импортировать большой файл CSV на сервер SQL. Я использую это:

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

проблема в том, что все мои поля заключены в кавычки (""), поэтому строка выглядит примерно так:

"1","","2","","sometimes with comma , inside", "" 

Могу ли я как-то массово импортировать их и указать SQL использовать кавычки в качестве разделителей полей?

Редактировать : Проблема с использованием «,» в качестве разделителя, как в предложенных примерах, заключается в том, что: Большинство примеров делают то, что они импортируют данные, включая первый «в первом столбце и последний» в последнем, а затем идут дальше и удаляют это. Увы, мой первый (и последний) столбец - datetime и не позволяет импортировать 20080902 как datetime.

Из того, что я читал, я думаю, FORMATFILE - это то, что нужно, но документация (включая MSDN) ужасно бесполезна.

Ответы [ 14 ]

13 голосов
/ 19 сентября 2008

Попробуйте FIELDTERMINATOR='","'

Вот отличная ссылка, чтобы помочь с первой и последней цитатой ... посмотрите, как он использовал подстроку SP

http://www.sqlteam.com/article/using-bulk-insert-to-load-a-text-file

9 голосов
/ 30 сентября 2008

Еще один хак, который я иногда использую, - это открыть CSV в Excel, а затем записать свой SQL-оператор в ячейку в конце каждой строки. Например:

=concatenate("insert into myTable (columnA,columnB) values ('",a1,"','",b1,"'")")

Заполнение может заполнить это в каждом ряду для вас. Затем просто скопируйте и вставьте вывод в новое окно запроса.

Это старая школа, но если вам нужно время от времени выполнять импорт, это избавит вас от необходимости возиться с чтением всей непонятной документации о «правильном» способе сделать это.

4 голосов
/ 19 сентября 2008

Попробуйте OpenRowSet . Это может быть использовано для импорта материалов Excel. Excel может открывать файлы CSV, поэтому вам нужно только определить правильную [ConnectionString] [2].

[2]: Driver = {Microsoft Text Driver (* .txt; * .csv)}; Dbq = c: \ txtFilesFolder \; Расширения = asc, csv, tab, txt;

3 голосов
/ 19 сентября 2008

Я знаю, что это ненастоящее решение, но я использую фиктивную таблицу для импорта с установленным nvarchar для всего. Затем я делаю вставку, которая удаляет символы и выполняет преобразования. Это не красиво, но выполняет свою работу.

2 голосов
/ 18 октября 2008

Я бы сказал, использовать FileHelpers - это библиотека с открытым исходным кодом.

1 голос
/ 21 сентября 2013

Сначала вам нужно импортировать файл CSV в таблицу данных

Затем вы можете вставить объемные строки, используя SQLBulkCopy

using System;
using System.Data;
using System.Data.SqlClient;

namespace SqlBulkInsertExample
{
    class Program
    {
      static void Main(string[] args)
        {
            DataTable prodSalesData = new DataTable("ProductSalesData");

            // Create Column 1: SaleDate
            DataColumn dateColumn = new DataColumn();
            dateColumn.DataType = Type.GetType("System.DateTime");
            dateColumn.ColumnName = "SaleDate";

            // Create Column 2: ProductName
            DataColumn productNameColumn = new DataColumn();
            productNameColumn.ColumnName = "ProductName";

            // Create Column 3: TotalSales
            DataColumn totalSalesColumn = new DataColumn();
            totalSalesColumn.DataType = Type.GetType("System.Int32");
            totalSalesColumn.ColumnName = "TotalSales";

            // Add the columns to the ProductSalesData DataTable
            prodSalesData.Columns.Add(dateColumn);
            prodSalesData.Columns.Add(productNameColumn);
            prodSalesData.Columns.Add(totalSalesColumn);

            // Let's populate the datatable with our stats.
            // You can add as many rows as you want here!

            // Create a new row
            DataRow dailyProductSalesRow = prodSalesData.NewRow();
            dailyProductSalesRow["SaleDate"] = DateTime.Now.Date;
            dailyProductSalesRow["ProductName"] = "Nike";
            dailyProductSalesRow["TotalSales"] = 10;

            // Add the row to the ProductSalesData DataTable
            prodSalesData.Rows.Add(dailyProductSalesRow);

            // Copy the DataTable to SQL Server using SqlBulkCopy
            using (SqlConnection dbConnection = new SqlConnection("Data Source=ProductHost;Initial Catalog=dbProduct;Integrated Security=SSPI;Connection Timeout=60;Min Pool Size=2;Max Pool Size=20;"))
            {
                dbConnection.Open();
                using (SqlBulkCopy s = new SqlBulkCopy(dbConnection))
                {
                    s.DestinationTableName = prodSalesData.TableName;

                    foreach (var column in prodSalesData.Columns)
                        s.ColumnMappings.Add(column.ToString(), column.ToString());

                    s.WriteToServer(prodSalesData);
                }
            }
        }
    }
}
1 голос
/ 30 сентября 2008

вы можете попробовать этот код, который очень приятен, если хотите, это удалит ненужные точки с запятой из вашего кода. если, например, ваши данные такие:
"Келли", "Рейнольд", "kelly@reynold.com"

Bulk insert test1
from 'c:\1.txt' with ( 
    fieldterminator ='","'
    ,rowterminator='\n')

update test1<br>
set name =Substring (name , 2,len(name))
where name like **' "% '**

update test1
set email=substring(email, 1,len(email)-1)
where email like **' %" '**
1 голос
/ 19 сентября 2008

Вы должны остерегаться BCP / BULK INSERT, потому что ни BSP, ни Bulk Insert не справляются с этим хорошо, если цитирование несовместимо, даже с файлами форматирования (даже файлы формата XML не предоставляют опцию) и фиктивной ["] символы в начале и конце и с использованием [","] в качестве разделителя. Технически CSV-файлы не обязательно должны иметь символы ["], если нет встроенных символов [,]

По этой причине файлы, разделенные запятыми, иногда называют файлами с ограниченным комедийным расширением.

OpenRowSet потребует Excel на сервере и может быть проблематичным в 64-битных средах - я знаю, что проблематично использовать Excel в Jet в 64-битных.

SSIS - это действительно ваша лучшая ставка, если файл в будущем может отличаться от ваших ожиданий.

1 голос
/ 19 сентября 2008

Вам нужно сделать это программно или это одноразовый снимок?

Используя Enterprise Manager, щелкните правой кнопкой мыши Импорт данных, чтобы выбрать разделитель.

0 голосов
/ 11 декабря 2018

Это старый вопрос, поэтому я пишу его, чтобы помочь любому, кто наткнется на него.

SQL Server 2017 вводит параметр FIELDQUOTE, который предназначен для этого конкретного случая использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...