Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用c从分隔文本文件在SQL Server表中大容量插入数据#_C#_Sql_Bulkinsert - Fatal编程技术网

C# 使用c从分隔文本文件在SQL Server表中大容量插入数据#

C# 使用c从分隔文本文件在SQL Server表中大容量插入数据#,c#,sql,bulkinsert,C#,Sql,Bulkinsert,我有制表符分隔的文本文件。文件大小约为100MB。我想将此文件中的数据存储到SQL server表中。该文件存储在sql server中时包含100万条记录。实现这一目标的最佳方式是什么 我可以在c#中创建momory datatable,然后将其上载到sql server,但在这种情况下,它会将整个100 MB的文件加载到内存中。如果文件大小变大怎么办?没问题;将处理大多数分隔文本格式,并实现IDataReader,因此可用于馈送SqlBulkCopy。例如: using (var file

我有制表符分隔的文本文件。文件大小约为100MB。我想将此文件中的数据存储到SQL server表中。该文件存储在sql server中时包含100万条记录。实现这一目标的最佳方式是什么

我可以在c#中创建momory datatable,然后将其上载到sql server,但在这种情况下,它会将整个100 MB的文件加载到内存中。如果文件大小变大怎么办?

没问题;将处理大多数分隔文本格式,并实现
IDataReader
,因此可用于馈送
SqlBulkCopy
。例如:

using (var file = new StreamReader(path))
using (var csv = new CsvReader(file, true)) // true = first row is headers
using (var bcp = new SqlBulkCopy(connectionString))
{
    bcp.DestinationTableName = "Foo";
    bcp.WriteToServer(csv);
}

请注意,
CsvReader
有很多选项,可以更精细地处理文件(指定分隔符规则等)
SqlBulkCopy
是高性能的批量加载API—非常高效。这是一个流式读写器API;它不会一次将所有数据加载到内存中。

您应该逐行读取文件,因此不必将整行数据加载到内存中:

using (var file = System.IO.File.OpenText(filename))
{
    while (!file.EndOfStream)
    {
        string line = file.ReadLine();

        // TODO: Do your INSERT here
    }
}
*更新*


“这将向sql server生成100万个单独的insert命令。有没有办法批量生成?”

您可以使用参数化查询,它仍然会发出1M个插入,但速度仍然相当快

或者,您可以使用
SqlBulkCopy
,但如果您不想使用第三方库,这将是相当困难的。如果您更适合MS许可证,可以使用(在MS PL许可证下分发),它提供了
AsDataReader
扩展方法:

void MyInsertMethod()
{
    using (var bulk = new SqlBulkCopy("MyConnectionString"))
    {
        bulk.DestinationTableName = "MyTableName";
        bulk.WriteToServer(GetRows().AsDataReader());
    }
}

class MyType
{
    public string A { get; set; }
    public string B { get; set; }
}

IEnumerable<MyType> GetRows()
{
    using (var file = System.IO.File.OpenText("MyTextFile"))
    {
        while (!file.EndOfStream)
        {
            var splitLine = file.ReadLine().Split(',');

            yield return new MyType() { A = splitLine[0], B = splitLine[1] };
        }
    }
}
void MyInsertMethod()
{
使用(var bulk=new SqlBulkCopy(“MyConnectionString”))
{
bulk.DestinationTableName=“MyTableName”;
bulk.WriteToServer(GetRows().AsDataReader());
}
}
类MyType
{
公共字符串A{get;set;}
公共字符串B{get;set;}
}
IEnumerable GetRows()
{
使用(var file=System.IO.file.OpenText(“MyTextFile”))
{
而(!file.EndOfStream)
{
var splitLine=file.ReadLine().Split(',');
返回新的MyType(){A=splitLine[0],B=splitLine[1]};
}
}
}

如果您也不想使用MS许可代码,您可以自己实现
IDataReader
,但这将是一个PITA。请注意,上面的CSV处理(
Split(',')
)一点也不可靠,而且表中的列名必须与
MyType
上的属性名相同。TBH,我建议您在这个问题上使用Marc的答案

为什么不使用
批量插入
命令?@pst如果我没有弄错的话,这要求文件与SQL server位于同一台服务器上,这可能是未来的一个问题poster@pst我有点假设海报从问题的措辞中知道如何做这一部分这将使100万个单独的insert命令进入sql server。有没有办法进去bulk@Cocowalla没有第三方库,为什么SqlBulkCopy很难复制?我正在按照以下方式进行操作,看起来很不错:SqlBulkCopy bulkCopy=newSQLBulkCopy(…)bulkCopy.BulkCopyTimeout=0;bulkCopy.DestinationTableName=“”;bulkCopy.WriteToServer(dt);其中dt是我通过解析文件填充的数据表。使用StreamReader。因为你说你担心内存使用。如果您使用的是
数据表
,则将整个文件加载到内存中。如果您不想这样做,也不想使用任何第三方库,那么您可能必须实现一个
IDataReader
yourself我理解。这是由某人开发的,并且是在麻省理工学院的开源许可之下。我正在寻找的是使用微软提供的SDK(API)实现同样目标的最佳方法。无需额外许可。@SamirLakhani麻省理工学院许可证非常开放,并授予您免费使用代码的许可证,前提是您将其许可证包含在您发行的作品中: