Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.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 Server - Fatal编程技术网

C# 使用C在SQL server中插入大量数据#

C# 使用C在SQL server中插入大量数据#,c#,sql-server,C#,Sql Server,我正在使用SQL Server 2012,有一个大约20 GB大小的巨大文件。我想把文件中的每一条记录都插入数据库。为此,我正在使用SqlBulkCopy类。但是由于数据量很大,我不得不一部分一部分地插入数据。代码如下: String line; SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["conStrtingName"].ConnectionString); conn.Open()

我正在使用SQL Server 2012,有一个大约20 GB大小的巨大文件。我想把文件中的每一条记录都插入数据库。为此,我正在使用
SqlBulkCopy
类。但是由于数据量很大,我不得不一部分一部分地插入数据。代码如下:

String line;
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["conStrtingName"].ConnectionString);
conn.Open();
StreamReader readFile = new StreamReader(filePath);
SqlTransaction transaction = conn.BeginTransaction();
try
{
    SqlBulkCopy copy = new SqlBulkCopy(conn, SqlBulkCopyOptions.KeepIdentity, transaction);
    copy.BulkCopyTimeout = 600;
    copy.DestinationTableName = "Txn";
    int counter = 0;
    while ((line = readFile.ReadLine()) != null)
    {
        string[] fields = line.Split('\t');
        if (fields.Length == 3)
        {
            DateTime date = Convert.ToDateTime(fields[0]);
            decimal txnCount = Convert.ToDecimal(fields[1]);
            string merchantName = fields[2];
            if (!string.IsNullOrEmpty(merchantName))
            {
                long MerchantId = Array.IndexOf(Program.merchantArray, merchantName) + 1;
                tables[workerId].Rows.Add(MerchantId, date, txnCount);
                counter++;
                if (counter % 100000 == 0)
                    Console.WriteLine("Worker: " + workerId + " - Transaction Records Read: " + counter);
                if (counter % 1000000 == 0)
                {
                    copy.WriteToServer(tables[workerId]);
                    transaction.Commit();
                    tables[workerId].Rows.Clear();
                    //transaction = conn.BeginTransaction();
                    Console.WriteLine("Worker: " + workerId + " - Transaction Records Inserted: " + counter);
                }
            }
        }
    }
    Console.WriteLine("Total Transaction Records Read: " + counter);
    if (tables[workerId].Rows.Count > 0)
    {
        copy.WriteToServer(tables[workerId]);
        transaction.Commit();
        tables[workerId].Rows.Clear();
        Console.WriteLine("Worker: " + workerId + " - Transaction Records Inserted: " + counter);
    }
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
    transaction.Rollback();
}
finally
{
    conn.Close();
}
它适用于前100000张唱片。但是,对于下一组记录,我得到一个异常
该事务要么与当前连接不关联,要么已完成。

当控件到达
transaction.Commit()时会发生这种情况


我能有一个解决办法吗

您可以这样增加事务的超时时间(使用与预期事务长度相适应的值)。以下代码持续15分钟:


您可以这样增加事务的超时时间(使用与预期事务长度相适应的值)。以下代码持续15分钟:


您可以这样增加事务的超时时间(使用与预期事务长度相适应的值)。以下代码持续15分钟:


您可以这样增加事务的超时时间(使用与预期事务长度相适应的值)。以下代码持续15分钟:


您的事务每100000集提交一次。所以它已经“消失”,您必须使用transaction=conn.BeginTransaction启动另一个


也许重新编写代码以更好地反映事务的生命周期是好的。您还可能需要确保使用新事务重新创建“复制”。

您的事务每100000次提交一次。所以它已经“消失”,您必须使用transaction=conn.BeginTransaction启动另一个


也许重新编写代码以更好地反映事务的生命周期是好的。您还可能需要确保使用新事务重新创建“复制”。

您的事务每100000次提交一次。所以它已经“消失”,您必须使用transaction=conn.BeginTransaction启动另一个


也许重新编写代码以更好地反映事务的生命周期是好的。您还可能需要确保使用新事务重新创建“复制”。

您的事务每100000次提交一次。所以它已经“消失”,您必须使用transaction=conn.BeginTransaction启动另一个


也许重新编写代码以更好地反映事务的生命周期是好的。您还可能需要确保使用新事务重新创建“复制”。

问题在于事务提交后的注释行。您需要取消对它的注释,并且重新初始化
SqlBulkCopy副本
变量。您最好重构您的代码,您需要事务和复制对象的唯一位置是当您刷新正在填充的数据表时,就像这样(您可以进一步将重复部分分解为单独的方法):


现在的问题是,如果出现问题,您无法回滚所有更改。可能更好的解决方案是不手动拆分批量插入,而是使用某种
IDataReader
实现,以避免在内存中填充巨大的
数据表(例如使用的)。

问题是事务提交后的注释行。您需要取消对它的注释,并且重新初始化
SqlBulkCopy副本
变量。您最好重构您的代码,您需要事务和复制对象的唯一位置是当您刷新正在填充的数据表时,就像这样(您可以进一步将重复部分分解为单独的方法):


现在的问题是,如果出现问题,您无法回滚所有更改。可能更好的解决方案是不手动拆分批量插入,而是使用某种
IDataReader
实现,以避免在内存中填充巨大的
数据表(例如使用的)。

问题是事务提交后的注释行。您需要取消对它的注释,并且重新初始化
SqlBulkCopy副本
变量。您最好重构您的代码,您需要事务和复制对象的唯一位置是当您刷新正在填充的数据表时,就像这样(您可以进一步将重复部分分解为单独的方法):


现在的问题是,如果出现问题,您无法回滚所有更改。可能更好的解决方案是不手动拆分批量插入,而是使用某种
IDataReader
实现,以避免在内存中填充巨大的
数据表(例如使用的)。

问题是事务提交后的注释行。您需要取消对它的注释,并且重新初始化
SqlBulkCopy副本
变量。您最好重构您的代码,您需要事务和复制对象的唯一位置是当您刷新正在填充的数据表时,就像这样(您可以进一步将重复部分分解为单独的方法):


现在的问题是,如果出现问题,您无法回滚所有更改。可能更好的解决方案是不手动拆分批量插入,而是使用某种
IDataReader
实现,以避免在内存中填充巨大的
DataTable
(例如使用的).

这可能会有帮助:您是否在任务管理器中检查了应用程序的内存使用情况?@MahmoudGamal:在该链接中,创建了多个bulkCopy对象。是否像使用1个大容量复制对象一样,只允许1个事务?因为我们提交了事务,所以第一个事务就完成了
using (TransactionScope scope = 
             new TransactionScope(TransactionScopeOption.Required, 
                                   new System.TimeSpan(0, 15, 0)))
  {
      // working code here
  }
String line;
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["conStrtingName"].ConnectionString);
conn.Open();
StreamReader readFile = new StreamReader(filePath);
SqlTransaction transaction = null;
try
{
    int counter = 0;
    while ((line = readFile.ReadLine()) != null)
    {
        string[] fields = line.Split('\t');
        if (fields.Length == 3)
        {
            DateTime date = Convert.ToDateTime(fields[0]);
            decimal txnCount = Convert.ToDecimal(fields[1]);
            string merchantName = fields[2];
            if (!string.IsNullOrEmpty(merchantName))
            {
                long MerchantId = Array.IndexOf(Program.merchantArray, merchantName) + 1;
                tables[workerId].Rows.Add(MerchantId, date, txnCount);
                counter++;
                if (counter % 100000 == 0)
                    Console.WriteLine("Worker: " + workerId + " - Transaction Records Read: " + counter);
                if (counter % 1000000 == 0)
                {
                    transaction = conn.BeginTransaction()
                    SqlBulkCopy copy = new SqlBulkCopy(conn, SqlBulkCopyOptions.KeepIdentity, transaction);
                    copy.BulkCopyTimeout = 600;
                    copy.DestinationTableName = "Txn";
                    copy.WriteToServer(tables[workerId]);
                    transaction.Commit();
                    transaction = null;
                    tables[workerId].Rows.Clear();
                    Console.WriteLine("Worker: " + workerId + " - Transaction Records Inserted: " + counter);
                }
            }
        }
    }
    Console.WriteLine("Total Transaction Records Read: " + counter);
    if (tables[workerId].Rows.Count > 0)
    {
        transaction = conn.BeginTransaction()
        SqlBulkCopy copy = new SqlBulkCopy(conn, SqlBulkCopyOptions.KeepIdentity, transaction);
        copy.BulkCopyTimeout = 600;
        copy.DestinationTableName = "Txn";
        copy.WriteToServer(tables[workerId]);
        transaction.Commit();
        transaction = null;
        tables[workerId].Rows.Clear();
        Console.WriteLine("Worker: " + workerId + " - Transaction Records Inserted: " + counter);
    }
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
    if (transaction != null) transaction.Rollback();
}
finally
{
    conn.Close();
}