我正在使用带有.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]下一个查询。我一直在尝试阅读多线程处理,但仍然找到了一个舒适的解决方案。非常感谢任何帮助。
答案 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()