您建议将.csv文件导入Microsoft SQL Server 2008 R2的方法是什么?
我想要一些快速的东西,因为我有一个包含大量.csv文件的目录(分布在500 .csv文件中的500MB左右)。
我在Win 7 x64上使用SQL Server 2008 R2。
更新:解决方案
以下是我解决问题的方法:
这种方法读取.csv文件的速度非常快? Microsoft SQL Server可以使用自己的高度优化的例程将文件直接从硬盘驱动器直接导入数据库。大多数其他基于C#的解决方案需要更多代码,而有些(如LINQ to Entities)最终必须通过C#-to-SQL-server链接将数据缓慢地传输到数据库中。
是的,我知道拥有100%纯C#代码来做这项工作更好,但最终:
答案 0 :(得分:7)
在T-SQL脚本中使用BULK INSERT似乎是一个很好的解决方案。
您可以使用xp_cmdshell和dir命令(稍微清理)获取目录中的文件列表。在过去,我尝试使用sp_OAMethod和VBScript函数执行类似的操作,并且必须使用dir方法,因为我无法使用FSO对象获取文件列表。
http://www.sqlusa.com/bestpractices2008/list-files-in-directory/
答案 1 :(得分:3)
如果您必须对除插入文件之外的文件中的数据执行任何操作,那么我建议您使用SSIS。它不仅可以插入和/或更新,还可以为您清理数据。
答案 2 :(得分:2)
第一种官方支持的导入大型文本文件的方法是使用命令行工具“bcp”(批量复制实用程序),对大量二进制数据非常有用。
请查看此链接:http://msdn.microsoft.com/en-us/library/ms162802.aspx
但是,在SQL Server 2008中,我假设BULK INSERT命令是您的首选,因为它首先成为标准命令集的一部分。如果由于任何原因你必须保持垂直兼容性,我会坚持使用bcp实用程序,也可用于SQL Server 2000.
HTH:)
稍后编辑:谷歌搜索我还记得SQL Server 2000也有BULK INSERT命令......但是,显然有一些原因我坚持使用bcp.exe,我不记得为什么......或许有一些限制,我想。
答案 3 :(得分:2)
我应该推荐这个:
using System;
using System.Data;
using Microsoft.VisualBasic.FileIO;
namespace ReadDataFromCSVFile
{
static class Program
{
static void Main()
{
string csv_file_path=@"C:\Users\Administrator\Desktop\test.csv";
DataTable csvData = GetDataTabletFromCSVFile(csv_file_path);
Console.WriteLine("Rows count:" + csvData.Rows.Count);
Console.ReadLine();
}
private static DataTable GetDataTabletFromCSVFile(string csv_file_path)
{
DataTable csvData = new DataTable();
try
{
using(TextFieldParser csvReader = new TextFieldParser(csv_file_path))
{
csvReader.SetDelimiters(new string[] { "," });
csvReader.HasFieldsEnclosedInQuotes = true;
string[] colFields = csvReader.ReadFields();
foreach (string column in colFields)
{
DataColumn datecolumn = new DataColumn(column);
datecolumn.AllowDBNull = true;
csvData.Columns.Add(datecolumn);
}
while (!csvReader.EndOfData)
{
string[] fieldData = csvReader.ReadFields();
//Making empty value as null
for (int i = 0; i < fieldData.Length; i++)
{
if (fieldData[i] == "")
{
fieldData[i] = null;
}
}
csvData.Rows.Add(fieldData);
}
}
}
catch (Exception ex)
{
}
return csvData;
}
}
}
//Copy the DataTable to SQL Server using SqlBulkCopy
function static void InsertDataIntoSQLServerUsingSQLBulkCopy(DataTable csvData)
{
using(SqlConnection dbConnection = new SqlConnection("Data Source=ProductHost;Initial Catalog=yourDB;Integrated Security=SSPI;"))
{
dbConnection.Open();
using (SqlBulkCopy s = new SqlBulkCopy(dbConnection))
{
s.DestinationTableName = "Your table name";
foreach (var column in csvFileData.Columns)
s.ColumnMappings.Add(column.ToString(), column.ToString());
s.WriteToServer(csvFileData);
}
}
}
答案 4 :(得分:1)
如果所有CSV的结构相同,我建议您使用Integration Services(SSIS)在它们之间循环并将它们全部插入到同一个表中。
答案 5 :(得分:1)
我知道这不是你的问题。但是,如果您遇到使用直插入的情况,请使用tablock并插入多行。取决于行大小,但我通常会在600-800行。如果它是加载到空表中,那么有时删除索引并在加载后创建它们会更快。如果可以在聚集索引加载之前对其进行排序。如果可以,请使用IGNORE_CONSTRAINTS和IGNORE_TRIGGERS。如果可以,请将数据库置于单用户模式。
USE AdventureWorks2008R2; 走 使用(tablock)插入Production.UnitMeasure VALUES(N'FT2',N'Square Feet','20080923'),(N'Y',N'Yards','20080923'),(N'Y3',N'Cubic Yards','20080923') ; GO