【问题标题】:How to insert data quickly into SQL Server using a stored procedure如何使用存储过程将数据快速插入 SQL Server
【发布时间】:2014-08-16 04:55:49
【问题描述】:

我有一个 C# 应用程序,它接收来自不同客户端的数据并将该数据插入 SQL Server。我每秒获取数据,甚至更快,但我的代码遇到了一些问题:

static SqlConnection objSqlConn = null;
static SqlCommand objSqlCmd = null;

public static void SaveClientHistory(String strMessage, String strClientIP)
{
    try
    {
        using (objSqlConn = new SqlConnection(strConnectionString))
        {
                using (objSqlCmd = new SqlCommand("procInsertHistory", objSqlConn))
                {
                    objSqlCmd.CommandTimeout = 0;
                    objSqlCmd.CommandType = CommandType.StoredProcedure;
                    objSqlCmd.Parameters.AddWithValue("@strMessage", strMessage);
                    objSqlCmd.Parameters.AddWithValue("@strClientIP", strClientIP);

                    objSqlConn.Open();
                    objSqlCmd.ExecuteNonQuery();
                }
        }
    }
    catch (Exception Ex)
    {
        throw Ex;
    }
    finally
    { 
        if(objSqlConn != null && objSqlConn.State != ConnectionState.Closed)
        {
            objSqlConn.Close();
            objSqlConn.Dispose();
        }
    }
}

发生了不同类型的异常:

连接没有关闭。连接的当前状态为正在连接。

内部连接致命错误。

ExecuteNonQuery 需要一个开放且可用的连接。连接的当前状态为正在连接。

如果上面的代码有任何错误,请告诉我或建议任何其他方式来完成此任务。

谢谢

【问题讨论】:

  • 请检查您是否错过了帖子中的一些细节,例如“我的应用程序并行处理多个请求”或“我不知道 static 是什么意思,需要解释”——它会让更容易诊断问题并提供修复。
  • 旁注:您能否也评论一下为什么代码需要关闭连接 3 次(using、.Close 和 .Dispose 在 finally 块中调用)。
  • 快到多快?
  • 我建议你使用 ORM,例如 MicrosoftEntityFrameWork OR Telerik OpenAcess
  • @Kyle... 快速意味着将近 200 个客户端以秒为间隔发送数据,应用程序应该能够在 SQL 中接收和存储数据。

标签: c# sql sql-server-2008


【解决方案1】:

已编辑 - 进一步简化了程序以更好地解决问题:删除了 try/catch,因为它没有做任何有用的事情;方法不再是static;现在所有输入都作为参数传入 - 包括strConnectionString;连接超时是明确设置的;在实例化SqlCommand 对象之前打开连接;命令超时现在是 10 秒。

由于性能是您关心的问题,请注意,您不必担心尝试保持连接打开以供重复使用。默认情况下,SQL Server 连接池是打开的,所以there is no need to attempt to cache connections with your own methodology。

除了尝试打开连接和执行非查询之外,似乎还有其他事情发生,因此我尝试进一步简化您的代码。我希望它有助于解决您的问题。

public int SaveClientHistory(String strConnectionString, String strMessage, String strClientIP)
{
    // You can double-up using statements like this (for slightly better readability)
    using (SqlConnection objSqlConn = new SqlConnection(strConnectionString))
    {
        objSqlConn.ConnectionTimeout = 10; // Creating a connection times out after ten seconds 
        objSqlConn.Open();
        using (SqlCommand objSqlCmd = new SqlCommand("procInsertHistory", objSqlConn))
        {
            objSqlCmd.CommandTimeout = 10; // Creating a command times out after ten seconds
            objSqlCmd.CommandType = CommandType.StoredProcedure;
            objSqlCmd.Parameters.AddWithValue("@strMessage", strMessage);
            objSqlCmd.Parameters.AddWithValue("@strClientIP", strClientIP);                 
            return objSqlCmd.ExecuteNonQuery();
        }
    }
}

【讨论】:

  • 感谢您的回复,当没有 finally 块时会遇到以下异常“连接未关闭。连接的当前状态为正在连接。”
  • @Muhammad 我重写了我的答案,它最初是一个建议更改列表,成为一个代码示例。我希望这会有所帮助!
  • 我已经更改了上面提到的代码,但仍然面临“ExecuteNonQuery 需要打开且可用的连接。连接的当前状态为正在连接。”...
  • strConnectionString 来自哪里?它里面有类似connect timeout=0 的东西吗?否则,我不确定为什么您的连接似乎卡在连接状态,但没有超时。
  • strConnectionString 只是简单的验证,它在类级别声明并在类构造函数中从 App.Config 设置,如 String strConndbRSuiteLive = ConfigurationManager.ConnectionStrings["ConnString"].ToString();
【解决方案2】:

似乎所有三个错误都与连接有关。在我的一个应用程序中,我实现了如下功能。希望对您有所帮助:

public static void SaveClientHistory(String strMessage, String strClientIP)
{
    SqlConnection objSqlConn = new SqlConnection(strConnectionString);
    SqlCommand objSqlCmd = new SqlCommand("procInsertHistory", objSqlConn)
    objSqlCmd.CommandType = CommandType.StoredProcedure;
    objSqlCmd.Parameters.AddWithValue("@strMessage", strMessage);
    objSqlCmd.Parameters.AddWithValue("@strClientIP", strClientIP);
    try{
        objSqlConn.Open();
        objSqlCmd.ExecuteNonQuery();               
    }
    catch (Exception Ex)
    {
        throw Ex;
    }
    finally
    { 
        if(objSqlConn.State == ConnectionState.Open)
            objSqlConn.Close();
    }
}

【讨论】:

  • 我已经更改了上面提到的代码,但仍然面临“ExecuteNonQuery 需要打开且可用的连接。连接的当前状态为正在连接。”...
  • 您的连接似乎是活跃的。尝试在打开之前关闭您的连接(它很脏但可能有效)。
  • 建议我,如果我只建立一个连接并保持打开状态并且每次只执行命令,它会顺利运行吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多