Массовый импорт SQL из CSV
-
01-07-2019 - |
Вопрос
Мне нужно импортировать большой 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) ужасно бесполезна.
Решение
Я знаю, что это не реальное решение, но я использую фиктивную таблицу для импорта с набором nvarchar для всего.Затем я делаю вставку, которая удаляет символы "" и выполняет преобразования.Это некрасиво, но делает свое дело.
Другие советы
Попробуй FIELDTERMINATOR='","'
Вот отличная ссылка, которая поможет с первой и последней цитатой...посмотрите, как он использовал подстроку the SP
http://www.sqlteam.com/article/using-bulk-insert-to-load-a-text-file
Еще один способ, которым я иногда пользуюсь, - открыть CSV-файл в Excel, затем записать свой sql-оператор в ячейку в конце каждой строки.Например:
=concatenate("insert into myTable (columnA,columnB) values ('",a1,"','",b1,"'")")
Функция заполнения может заполнить это значение в каждой строке для вас.Затем просто скопируйте и вставьте выходные данные в новое окно запроса.
Это старая школа, но если вам нужно только время от времени выполнять импорт, это избавит вас от необходимости читать всю непонятную документацию о "правильном" способе это сделать.
Попробуй Набор открытых данных.Это можно использовать для импорта материалов Excel.Excel может открывать CSV-файлы, поэтому вам нужно только правильно ввести [ConnectionString][2].
[2]:Драйвер={Текстовый драйвер Microsoft (*.txt;*.csv)};Dbq=c: xtFilesFolder\; Расширения=asc, csv, tab,txt;
Я бы сказал, используйте FileHelpers - это библиотека с открытым исходным кодом
Вам нужно сделать это программно, или это одноразовый снимок?
Используя Enterprise Manager, щелкните правой кнопкой мыши Импорт данных, чтобы выбрать нужный разделитель.
Вы должны быть осторожны с BCP / BULK INSERT, потому что ни BSP, ни Bulk Insert не справляются с этим хорошо, если цитирование не согласовано, даже с файлами формата (даже файлы формата XML не предлагают такую опцию) и фиктивными символами ["] в начале и конце и использованием [","] в качестве разделителя.Технически CSV-файлы не обязательно должны содержать символы ["], если в них нет встроенных символов [,]
Именно по этой причине файлы, разделенные запятыми, иногда называют файлами с ограниченным доступом.
OpenRowSet потребует Excel на сервере и может быть проблематичным в 64-разрядных средах - я знаю, что проблематично использовать Excel в Jet в 64-разрядной версии.
Служба SSIS действительно является вашим лучшим выбором, если файл в будущем может отличаться от ваших ожиданий.
вы можете попробовать этот код, который очень хорош, если хотите,
это удалит ненужные точки с запятой из вашего кода.если, например, ваши данные выглядят следующим образом :
"Келли", "Рейнольд","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 **' %" '**
Сначала вам нужно импортировать 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);
}
}
}
}
}
Да, Кей Ричард прав: FIELDTERMINATOR = '","'
Видишь http://www.sqlteam.com/article/using-bulk-insert-to-load-a-text-file для получения дополнительной информации.
Вы также можете использовать DTS или SSIS.
Есть ли у вас контроль над форматом ввода?| (трубы), и обычно обеспечивают лучшие терминаторы полей.
Если вы выясните, как преобразовать файл в DataTable, я бы предложил класс SqlBulkInsert для вставки его в SQL Server.
Это старый вопрос, поэтому я пишу это, чтобы помочь всем, кто наткнется на него.
SQL Server 2017 вводит параметр FIELDQUOTE, который предназначен именно для этого варианта использования.