C# 使用C在SQL server中插入大量数据#
我正在使用SQL Server 2012,有一个大约20 GB大小的巨大文件。我想把文件中的每一条记录都插入数据库。为此,我正在使用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()
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();
}