无法在Windows服务中执行SQL命令

时间:2011-06-30 19:43:38

标签: sql vb.net ado.net windows-services

我正在努力创建一个Windows服务,该服务会在客户提交过期后的一个月内向客户发送电子邮件。我在Visual Studios 2008中使用vb.net

因为它是一个Windows服务,所以很难调试。试图缩小我的错误我创建了一个“sendDebugEmail”方法,如果它到达某一行,它会向我发送一封电子邮件。电子邮件永远不会超过“dr = cmd.ExecuteReader()”

我想知道我做错了什么。我的SQL语句应该可以正常工作。我在我的SQL服务器数据库中测试过它。

我创建了一个我刚刚在sql server中创建的dummy_database。我为那里的虚拟表添加了一个INSERT sql语句,只是为了看看我是否可以实际访问数据库。所有表格都是行号和发送时间。当我运行我的Windows服务时,数据库更新就好了。

任何帮助将不胜感激。感谢

Dim conn As New SqlConnection(connString2)

    sendDebugEmail("134")

    SQL = "Select email FROM _Customer WHERE custID in (SELECT custID FROM _OnlineCustomer WHERE ExpirationDate <= '6-20-12' AND ExpirationDate >= '6-10-12')"
    Dim cmd As New SqlCommand(SQL, conn)


    sSubject = "hello"
    sBody = "This is test data"
    Dim dr As SqlDataReader

    sendDebugEmail("143")

    Try
        dr = cmd.ExecuteReader()   // This is were it stops

        sendDebugEmail("147")

        While dr.Read

            sendDebugEmail("152")

            Try
                LogInfo("Service woke up")
                Dim i As Integer = 0
                ' Prepare e-mail fields
                sFrom = "test@gmail.com"
                sTo = "test1@gmail.com"
                sCc = "test2@gmail.com"
                Dim oMailMsg As MailMessage = New MailMessage
                oMailMsg.From = sFrom
                oMailMsg.To = sTo
                oMailMsg.Cc = sCc
                ' Call a stored procedure to process the current item
                ' The success message
                oMailMsg.Subject = sSubject + "(Success)"
                oMailMsg.Body = sBody + "Email has been sent successfully."
                ' Send the message
                If Not (oMailMsg.To = String.Empty) Then
                    SmtpMail.Send(oMailMsg)
                End If

            Catch obug As Exception
                LogEvent(obug.Message)
            Finally

            End Try
        End While
    Catch ex As Exception

    Finally
        dr.Close()
        cmd.Dispose()
        conn.Close()
        conn.Dispose()
    End Try
End Sub

/////////////////////////////////////////////// //////////////////////////////////

解决问题:我建立了连接,但我从未打开它。
我需要conn.open()

最能帮助我的是将此代码添加到我的上一个catch语句中:

sendDebugEmail(ex.Message & vbcrlf & ex.stackTrace)

它向我发送了一封stackTrace的电子邮件,并且非常容易调试

4 个答案:

答案 0 :(得分:2)

您是否诱捕和吞咽异常?如果你是,停下来。让异常服务使服务崩溃:异常将记录在事件日志中。您应该捕获的唯一例外是您可以实际恢复的那些(尽管它有效以捕获异常,记录并通过throw;重新抛出它)。

您是否使用log4net(http://logging.apache.org/log4net/)或类似内容对您的代码进行了检测?您应该(特别是对于像Windows服务这样的守护进程) - 您(或操作)如何在发生时(如他们所愿)诊断服务问题。

编辑注:

  1. 您应该使用using语句:所有这些ADO.Net对象都是IDisposable。它使代码更清晰。

  2. 考虑使用SqlDataAdapter用结果集填充DataTable或DataSet。你正在使用的模式:

    read a row from SQL
    while read was successful
      send an email
      read a row from SQL
    

    最终会导致数据库阻塞。与邮件服务器通信可能会导致高延迟。如果邮件服务器没有应答,或者您遇到网络拥塞或其他任何原因,那么在发送邮件或由于超时而引发异常之前,您将一直处于挂起状态。并且你的SQL查询将坐在那里,桌面上有读锁和你正在读取数据的索引,阻止尝试进行更新,插入或删除的人。你的生产DBA会很烦恼。您希望保持锁定移动并尽快释放锁定。

答案 1 :(得分:1)

如果您确定您的代码(没有例外),我认为您应检查您用于连接SQL服务器的身份验证(在app.config文件/内联中的连接字符串内) Windows服务的代码。)

如果您正在使用SQL身份验证(检查用户名 sa 的连接字符串及其密码),则将Windows服务的帐户类型设置为 LocalService 将有助于您。

如果SQL连接使用的是Windows身份验证,那么将Windows服务的帐户类型设置为 LocalSystem 会对您有所帮助。

帐户类型修改也可以在安装后完成。为此,请转到控制面板 - &gt;管理工具 - &gt;服务 - &gt; YourService ,右键单击并选择属性 - >登录并在那里执行。如果您选择LocalSystem(Windows身份验证),系统将要求您输入运行该服务的帐户的登录凭据。

对于SQL连接中的Windows身份验证,运行服务的帐户的凭据也将用于SQL连接。

希望这会有所帮助......

答案 2 :(得分:0)

另一个建议是在你的过程启动时给你一个睡眠声明,所以oyu有时间附加它

答案 3 :(得分:0)

问题已解决:我设置了连接,但我从未打开过它 我需要conn.open()

最能帮助我的是将此代码添加到我的上一个catch语句中:

sendDebugEmail(ex.Message & vbcrlf & ex.stackTrace)

它向我发送了一封stackTrace的电子邮件,并且非常容易调试