【问题标题】:Error updating using SqlCommand使用 SqlCommand 更新时出错
【发布时间】:2014-02-10 21:00:24
【问题描述】:

执行代码时出错,我使用的是 C# & SQL Server 7 / 2000。

我正在做的步骤是:

  • 获得所有门票
  • 然后我阅读每张票
  • 传递给 Web 服务方法进行验证
  • 如果返回为真,我需要更新一个表。

请检查我的代码,感谢有关如何修复它的反馈.. 因为这几天让我发疯了!谢谢!

    public void Execute()
    {
        SqlConnection conn = null;
        SqlConnection conn2 = null; 
        SqlDataReader rdr = null;

        try
        {
            Helper helper = new Helper();
            using (conn = new SqlConnection(helper.MISDBConnectionString))
            {
                conn.Open();

                string ticketid = null;
                bool bTerm = false;
                int rowsAffected = 0;

                if (rdr != null) { rdr.Close(); }
                SqlCommand selectCommand = new SqlCommand();
                selectCommand.CommandText = "SELECT ...";
                selectCommand.Connection = conn;
                rdr = selectCommand.ExecuteReader();

                while (rdr.Read())
                {
                    ticketid = rdr["ticketid"].ToString();
                    bTerm = calling webserver for validation

                    if (bTerm)
                    {                           
                        using (conn2 = new SqlConnection(helper.MISDBConnectionString))
                        {
                            conn2.Open();
                            SqlCommand updateCommand = new SqlCommand();

                            updateCommand.CommandText = "UPDATE ticket  SET code = @code WHERE ticketid = @ticketid";
                            updateCommand.CommandType = CommandType.Text;
                            updateCommand.CommandTimeout = 120;
                            updateCommand.Parameters.AddWithValue("@code", 8);
                            updateCommand.Parameters.AddWithValue("@ticketid", ticketid);
                            updateCommand.Connection = conn2;

                            rowsAffected = updateCommand.ExecuteNonQuery(); //fails here
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            logger.Error(ex.ToString());
        }
        finally
        {
            if (conn != null) { conn.Close(); }
            if (conn2 != null) { conn2.Close(); }
            if (rdr != null) { rdr.Close(); }
        }
    }

我需要使用两个连接,因为如果我使用一个需要在更新之前关闭 dataReader 的连接,它会给我一个错误

我目前遇到的错误:

System.Data.SqlClient.SqlException (0x80131904):超时。这 在操作完成之前经过的超时时间或 服务器没有响应。在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常, 布尔中断连接)在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException 异常,布尔型 breakConnection) 在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() 在 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler、SqlDataReader 数据流、 BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) 在 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior,字符串 resetOptionsString) 在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior、RunBehavior runBehavior、布尔 returnStream、布尔 异步)在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior、runBehavior、布尔返回流、字符串 方法,DbAsyncResult 结果)在 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult 结果,字符串方法名称,布尔值 sendToPipe) 在 System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 在 GDR.UpdateTicket.Execute()

【问题讨论】:

    标签: c# sql-server-2000 sqldatareader sqlcommand sql-server-7


    【解决方案1】:

    很难判断是什么导致了您的超时,很可能是您造成了死锁。但是,我认为您应该首先更改以下内容:

    不要使用第二个连接,先读取所有数据,关闭阅读器,然后使用相同或另一个连接处理它。如果数据过多,请在页面中进行。

    我的意思是这样的

    List<string> ids = new List<string>
    
    while (rdr.Read())
    {
      ids.add(rdr["ticketid"].ToString())
    }
    
    rdr.Close();
    
    foreach(id in ids)
    {
     // ...
    

    另外,你不需要这样做

    if (conn != null) { conn.Close(); }
    if (conn2 != null) { conn2.Close(); } 
    

    using(conn=new ...) 语句为您执行此操作。

    【讨论】:

    • 谢谢,我认为这可以工作,我想做的不是将门票存储在任何地方,想要获取每个ticketid然后检查它,如果真的更新它,然后转到下一个ticketid。 .etc 这有意义吗?
    • 好吧,如果您不想存储它们(尽管我不明白为什么不这样做),您可以使用 ExecuteScalar() 逐一读取它们,因为您只返回一个值。这样效率会低很多。
    • 我必须同意 Anri 的观点,除非您的 SELECT 语句中有 100 多列,否则为什么不想将结果存储在 DataTable 中,然后遍历 DataTable?你是在 TRS-DOS80 上运行它吗?
    【解决方案2】:

    我同意 Anri 的观点,这很可能是由于锁定问题。您是否尝试在您的 SELECT 语句中使用 WITH (NOLOCK) 来查看是否可以解决问题?这应该允许您在迭代结果时更新表,而 SELECT 语句不会持有阻止 UPDATE 执行的读锁。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-31
      • 1970-01-01
      • 2011-09-12
      • 2017-03-11
      • 2018-06-08
      • 2017-04-14
      • 1970-01-01
      相关资源
      最近更新 更多