VB.net应用程序对于SQL查询循环来说太快了

时间:2015-02-23 15:48:12

标签: sql-server vb.net .net-4.0

我正在使用带有.Net 4.0的Visual Basic设计软件和MS SQL服务器后端来存储数据。我为数据库的“员工工资”部分设计了一个类。此类的子例程的目的是重置已准备好的工资表。每次用户“运行工资单”时,它都会使用[SELECT * INTO]方法创建当前关联表的备份。这部分通常效果很好,没有问题或问题。我遇到的问题是当我尝试[重置]工资单时,[DROPS]“已修改”的表再次使用[SELECT * INTO]方法从先前创建的备份重新创建表。以下是我编写的[RESET]代码示例。

Public Sub Reset_Payroll()
    Dim conn As New SqlConnection()
    conn.ConnectionString = _sqlConnector

    Dim varSQL(4) As String
    varSQL(0) = "DROP TABLE [EMPLOYEEWAGES]"
    varSQL(1) = "DROP TABLE [EMPLOYEECHECKS]"
    varSQL(2) = "DROP TABLE [EMPLOYEEREGISTAR]"
    varSQL(3) = "DROP TABLE [EMPLOYEEPAY]"

    For x As Integer = 0 To 3
        Try
            If conn.State = ConnectionState.Closed Then
                conn.Open()
            End If
            Dim cmd As New SqlCommand(varSQL(x), conn)
            cmd.ExecuteNonQuery()
            Application.DoEvents()
        Catch ex As Exception
            MsgBox("PLEASE REPORT THIS MESSAGE TO CIS DEPT: " & ex.ToString, vbOKOnly, "STAFF WAGES [CREATE WAGES_TEMP] GENERAL EXCEPTION ERROR.")
            'Utilities.CreateMessageAlert(_aspxPage, "PLEASE REPORT THIS MESSAGE TO CIS DEPT: " & ex.ToString, "strKey")
            conn.Close()
        End Try
    Next

    varSQL(0) = "SELECT * INTO [EMPLOYEEWAGES] FROM [EMPLOYEEWAGES_RUNCHK]"
    varSQL(1) = "SELECT * INTO [EMPLOYEECHECKS] FROM [EMPLOYEECHECKS_RUNCHK]"
    varSQL(2) = "SELECT * INTO [EMPLOYEEREGISTAR] FROM [EMPLOYEEREGISTAR_RUNCHK]"
    varSQL(3) = "SELECT * INTO [EMPLOYEEPAY] FROM [EMPLOYEEPAY_RUNCHK]"

    For x As Integer = 0 To 3
        Try
            If conn.State = ConnectionState.Closed Then
                conn.Open()
            End If
            Dim cmd As New SqlCommand(varSQL(x), conn)
            cmd.ExecuteNonQuery()
            Application.DoEvents()
        Catch ex As Exception
            MsgBox("PLEASE REPORT THIS MESSAGE TO CIS DEPT: " & ex.ToString, vbOKOnly, "STAFF WAGES [CREATE WAGES_TEMP] GENERAL EXCEPTION ERROR.")
            'Utilities.CreateMessageAlert(_aspxPage, "PLEASE REPORT THIS MESSAGE TO CIS DEPT: " & ex.ToString, "strKey")
        Finally
            conn.Close()
        End Try
    Next

    varSQL(0) = "DROP TABLE [EMPLOYEEWAGES_RUNCHK]"
    varSQL(1) = "DROP TABLE [EMPLOYEECHECKS_RUNCHK]"
    varSQL(2) = "DROP TABLE [EMPLOYEEREGISTAR_RUNCHK]"
    varSQL(3) = "DROP TABLE [EMPLOYEEPAY_RUNCHK]"

    For x As Integer = 0 To 3
        Try
            If conn.State = ConnectionState.Closed Then
                conn.Open()
            End If
            Dim cmd As New SqlCommand(varSQL(x), conn)
            Application.DoEvents()
            cmd.ExecuteNonQuery()
        Catch ex As Exception
            MsgBox("PLEASE REPORT THIS MESSAGE TO CIS DEPT: " & ex.ToString, vbOKOnly, "STAFF WAGES [CREATE WAGES_TEMP] GENERAL EXCEPTION ERROR.")
            'Utilities.CreateMessageAlert(_aspxPage, "PLEASE REPORT THIS MESSAGE TO CIS DEPT: " & ex.ToString, "strKey")
        Finally
            conn.Close()
        End Try
    Next

End Sub

我遇到问题的区域位于代码的第二部分,系统正在从备份表[WAGES_RUNCHK]重新创建工资,支票,注册表和支付表。看起来sql命令之间的for循环处理在前一个SQL查询完成之前执行得太快了。因此,某些表不会从备份中重新创建,并且数据正在丢失。我添加了application.DoEvents()但尚未投入生产。以前我必须实现thread.sleep()事件以尝试给它时间来处理,但我对这些解决方案中的任何一个都不满意。

是否有任何方法或方法可以实现暂停,直到上一个查询完成为止。允许系统与For循环中的SQL服务器通信: “先前的查询是否完成,如果是,那么[SELECT INTO]下一个查询。我一直在尝试阅读多线程处理,但仍然找到了一个舒适的解决方案。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:3)

我会创建一个包含所有12个语句的存储过程:

CREATE PROCEDURE dbo.resetPayroll 
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    DROP TABLE [EMPLOYEEWAGES]
    DROP TABLE [EMPLOYEECHECKS]
    DROP TABLE [EMPLOYEEREGISTAR]
    DROP TABLE [EMPLOYEEPAY]
    SELECT * INTO [EMPLOYEEWAGES] FROM [EMPLOYEEWAGES_RUNCHK]
    SELECT * INTO [EMPLOYEECHECKS] FROM [EMPLOYEECHECKS_RUNCHK]
    SELECT * INTO [EMPLOYEEREGISTAR] FROM [EMPLOYEEREGISTAR_RUNCHK]
    SELECT * INTO [EMPLOYEEPAY] FROM [EMPLOYEEPAY_RUNCHK]
    DROP TABLE [EMPLOYEEWAGES_RUNCHK]
    DROP TABLE [EMPLOYEECHECKS_RUNCHK]
    DROP TABLE [EMPLOYEEREGISTAR_RUNCHK]
    DROP TABLE [EMPLOYEEPAY_RUNCHK]
END

请注意,我的示例存储过程不包含任何错误捕获或报告。在交易中包装它可能是一个非常好的主意。

然后,您的代码将成为对数据库的单个调用:

Dim cmd as New SqlCommand("resetPayroll", conn)
cmd.CommandType = CommandType.StoredProcedure
cmd.ExecuteNonQuery()