【问题标题】:c# program : Getting error with SQLTransaction commands with lot of INSERT statementsc#程序:使用大量INSERT语句的SQLTransaction命令出错
【发布时间】:2013-10-17 13:09:48
【问题描述】:

更新 1:以下代码在我的 DEV 机器上运行良好,但在测试/生产服务器上失败。

public TransImport()
{
ConnString = ConfigurationManager.ConnectionStrings["Connection"].ConnectionString;
SqlConnection conn_new;
SqlCommand command_serial_new;
SqlTransaction InsertUpdateSerialNumbers;

conn_new = new SqlConnection(ConnString);
command_serial_new = conn_new.CreateCommand();
command_serial_new.CommandText = "SELECT 1 FROM YSL00020 WITH (NOLOCK) WHERE SERLNMBR = @slnr";
var p = new SqlParameter("@slnr", SqlDbType.NVarChar, 50);
command_serial_new.Parameters.Add(p);

InsertUpdateSerialNumbers = conn.BeginTransaction();
boolean bErrors = false;
while (!headerFileReader.EndOfStream)
{
     headerRow = headerFileReader.ReadLine();

     if (!CheckSerialNumber(headerFields[0].Trim()))
        {
        bErrors = true;
        break;
        }
  }
if (bErrors)
  InsertUpdateSerialNumbers.Commit();
else
  InsertUpdateSerialNumbers.Rollback();

if (conn_new != null)
{
    conn_new.Close();
    conn_new.Dispose();
}

}

private Boolean CheckSerialNumber(string SerialNumber)
{
command_serial_new.Parameters["@slnr"].Value = SerialNumber;
try
{
    var itExists = Convert.ToInt32(command_serial_new.ExecuteScalar()) > 0;
    if (!itExists)
    {
        command_serial.Transaction = InsertUpdateSerialNumbers;
        command_serial.CommandText = "INSERT INTO YSL00([Manifest_Number],[PONUMBER],[ITEMNMBR],[SERLNMBR]"
         + "VALUES ('" + Manifest + "','" + PONr + "','" + itemNumber + "','" + serialNr  + "')";
        var insertStatus = command_serial.ExecuteNonQuery();
        return true;
    }
}
catch (Exception ex)
{
    LogException(ex, "Error in CheckSerialNumber =>"+ command_serial_new.CommandText.ToString());
}
return false;
}

我在上面的代码中遇到的问题:

我正在使用带有提交和回滚的 SQLTransaction。我遍历一个平面文件并更新一些表。文件通常包含大约 500 到 1000 行。我正在为每一行(使用 sqltransaction)创建 INSERT 语句,并且程序在 COMMIT 语句处暂停很长时间,最终我得到如下所示的错误。但是,如果我注释掉整个 sqltransaction(以及提交和回滚),一切都很好,但我们需要提交和回滚。有没有办法只创建一个事务(我现在正在为每个 INSERT 语句创建),这样我就不会收到如下错误。

System.ServiceModel.CommunicationException

从管道读取错误:管道已结束。 (109, 0x6d)。 mscorlib

服务器堆栈跟踪: 在 System.ServiceModel.Channels.StreamConnection.Read(字节 [] 缓冲区,Int32 偏移量,Int32 大小,TimeSpan 超时) 在 System.ServiceModel.Channels.SessionConnectionReader.Receive(时间跨度超时) 在 System.ServiceModel.Channels.SynchronizedMessageSource.Receive(时间跨度超时) 在 System.ServiceModel.Channels.FramingDuplexSessionChannel.Receive(时间跨度超时) 在 System.ServiceModel.Channels.FramingDuplexSessionChannel.TryReceive(时间跨度超时,消息和消息) 在 System.ServiceModel.Dispatcher.DuplexChannelBinder.Request(消息消息,TimeSpan 超时) 在 System.ServiceModel.Channels.ServiceChannel.Call(字符串操作,布尔单向,ProxyOperationRuntime 操作,Object[] 输入,Object[] 输出,TimeSpan 超时) 在 System.ServiceModel.Channels.ServiceChannel.Call(字符串操作,布尔单向,ProxyOperationRuntime 操作,Object[] 输入,Object[] 输出) 在 System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime 操作) 在 System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage 消息)

在 [0] 处重新抛出异常: 在 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg,IMessage retMsg) 在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 类型)

【问题讨论】:

  • SQL Injection alert - 您应该将您的 SQL 语句(如您的 INSERT)连接在一起 - 使用 参数化查询 来避免 SQL 注入

标签: c# pipe commit bulkinsert sqltransaction


【解决方案1】:

有助于改善这一点的几件事。

首先将SqlConnection 命令包装在using 中。

第二个听起来像 prod 需要更长的时间来运行它,这就是它超时的原因。您可以将超时设置为无限制。

最后,如果您使用的是 SQL Server 2008+,您应该使用批量插入。

Insert into table (column1, column2) values (value1, value2), (value3, value4)

动态构建这些值时的另一个注意事项是一次控制一千个值的限制。

【讨论】:

  • 我已经尝试了使用 USING 的 sqlconnection 命令,但到目前为止没有任何帮助。如何进行批量插入?这可能对我有用,因为它只是 SQLTransaction 的一个事务,但是我必须考虑查询的长度?
【解决方案2】:

使用批量插入修改了我的代码,没有任何问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 2011-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多