【问题标题】:Concept of handling SqlCommand in C#C#中处理SqlCommand的概念
【发布时间】:2013-09-11 09:25:11
【问题描述】:

我正在尝试从数据库中选择一个用户列表,并根据条件 isSent == false 向每个用户发送电子邮件。向他们发送电子邮件后,此 false 的值应更新为 true。下面的代码是我从数据库中检索用户列表并向每个用户调用方法 sendEmail() 的方式。

           myConnection.Open();
            //*******
            try
            {
                SqlDataReader myReader = null;
                string sql = "SELECT * FROM testTable where isSent = false";
                SqlCommand myCommand = new SqlCommand(sql, myConnection);
                myReader = myCommand.ExecuteReader();

                while (myReader.Read())
                {
                    sendEmail(myReader["emailAdd"].ToString(), 
                              myReader["UserID"].ToString());
                }

第二部分:

public static void sendEmail(string emailAdd,string userID){
    .
    .
    .
    try
    {
        smtpClient.Send(mail);
        try
            {
                string sql = "UPDATE testTable SET isSent = 1 WHERE  UserID = " + userID;
                SqlCommand myCommand = new SqlCommand(sql, myConnection);
                int rows = myCommand.ExecuteNonQuery();
                .
                .
                .
            }
    }
}

我面临的问题是,由于从 main 方法我已经有 SqlDataReader 被保持读取,所以我现在无法更新。有什么适合我的工作吗?我得到的错误信息如下:

There is already an open DataReader associated with this Command which must be closed first.

【问题讨论】:

    标签: c# sql sqldatareader sqlconnection


    【解决方案1】:

    我面临的问题是,由于从 main 方法我已经拥有 SqlDataReader 可以读取,所以我现在无法更新。有什么适合我的吗?

    这只是一个问题,因为您正在共享连接 (myConnection)。不要那样做。每次要执行数据库操作时创建一个新的SqlConnection,并让连接池基础结构处理使其高效。此外,对数据库相关资源使用using 语句:

    using (var connection = new SqlConnection(...))
    {
        using (var command = new SqlCommand(...))
        {
            using (var reader = command.ExecuteReader(...))
            {
                ...
            }
        }
    }
    

    【讨论】:

    • 如果我没有正确理解它,我很抱歉,因为它仍然在抱怨同样的错误。我在我的主要方法中使用你的代码 sn-p,在我的 sendMail 方法中使用另一组代码( ),它应该工作正常吗?
    • @IsaacLem:你还没有告诉我们你在说什么错误,这使得很难说什么是错误的。但是,是的,如果您在每段代码中创建一个单独的连接,从这个角度来看应该没问题。在事务性方面可能存在问题(在更新它所处理的数据时从查询中读取),但这是另一回事。
    • 我已经编辑了包含错误消息的问题。两种方式都给我同样的错误信息。想象一下第一个查询返回了 3 行 A、B 和 C。我现在正在尝试更新 A 行的一列。会有什么问题吗?
    • 当您有两个完全独立的连接、命令和读取器时,您不应该遇到该异常。你确定你的新代码看起来像我的,声明new变量等等吗?
    • 我的错。我倾向于创建另一个具有相同名称的变量,让它覆盖旧的变量,这显然会给出错误。非常感谢!
    【解决方案2】:

    作为另一种选择。您可以将其添加到数据库的连接字符串中。

    MultipleActiveResultSets=True

    性能略有下降。旧版 SQL Server 不支持它。我认为是 2005 年之前

    【讨论】:

    • 我正在使用 sqlConnection,如下所示: static SqlConnection myConnection = new SqlConnection("user id=xxx;" + "password=xxx;server=xxx;" + "Trusted_Connection=yes;" +“数据库=xxx;”+“连接超时=30”);你的方法不可行吗?
    • 根据 SQL Server 的版本,您只需将 MultipleActiveResultSets=true 添加到字符串中,即 new SqlConnection("user id=xxx;" + "password=xxx;server=xxx; " + "Trusted_Connection=yes;" + "database=xxx; " + "连接超时=30;multipleactiveresultsets=true");
    • 我使用的是 SSMS 2008,它给了我一个 sqlinitialize 异常
    【解决方案3】:

    试试这个代码..`

     public static void sendEmail(string emailAdd,string userID){
      try
        {
            SqlConnection con = new SqlConnection(@"");
            con.Open();
    
            MailMessage mail = new MailMessage("example@gmail.com", emailAdd);
            SmtpClient smtpClient = new SmtpClient();
            NetworkCredential nc = new NetworkCredential("example@gmail.com", "test");
    
            smtpClient.Port = 587;
            smtpClient.Host = "smtp.gmail.com";
            smtpClient.EnableSsl = true;
            smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
            smtpClient.UseDefaultCredentials = false;
           // smtpClient.Host = "smtp.google.com";
            mail.Subject = "this is a test email.";
            mail.Body = "this is my test email body";
            smtpClient.Credentials = nc;
            smtpClient.Send(mail);
    
            using (SqlCommand cmd = con.CreateCommand())
            {
                string sql = "UPDATE TestTable SET IsSent = 'true' WHERE  UserID = " + userID;
                SqlCommand myCommand = new SqlCommand(sql, con);
                int rows = myCommand.ExecuteNonQuery();
            }
        }
        catch(Exception e)
        {
            string message = e.Message;
        }`
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-05
      • 2018-08-21
      相关资源
      最近更新 更多