我从我的 VB.NET Windows 窗体应用程序调用的 SQL Server 更新查询有问题。当用户单击按钮停止我的时间输入应用程序中的时间输入时,将调用 SqlConnection 查询。用户第一次单击该按钮时,查询被执行并且看起来是成功的。但是,查看数据库显示它没有更新。用户第二次单击该按钮时,数据库行得到正确更新。总是需要尝试 2 次才能成功。
按钮点击代码
Private Sub btnStop_Click(sender As Object, e As EventArgs) Handles btnStop.Click
Timer.Stop()
Dim hasActiveTimeEntry As Boolean
clsTimeTracker.EndTimeEntry(timeEntry)
ClearActiveTimeEntryDisplay()
RefreshActiveTimeEntryDisplay()
LoadCompletedTimeEntryGrid(user, timeEntryList)
LoadProjectListGrid(user, projList)
hasActiveTimeEntry = clsTimeTracker.GetActiveTimeEntry(user, timeEntry)
End Sub
SQL查询代码
Public Shared Function EndTimeEntry(newTimeEntry As clsTimeEntry) As Boolean
Dim res As Boolean = False
With newTimeEntry
.actClockOutTime = DateTime.Now()
.Complete = True
Dim sqlString As String = ""
sqlString = " UPDATE TimeEntry Set Complete = @Complete, Note = @Note, actEndTime = @actEndTime, EndTime = @EndTime, Hours = @Hours where TimeEntryID = @TimeEntryID"
Using con As New SqlConnection(clsCheckDBConnection.ConnStrTimeTrackerDB)
Using cmd As New SqlCommand(sqlString, con)
cmd.CommandType = CommandType.Text
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@TimeEntryID", .SqlDbType = SqlDbType.Int, .Value = newTimeEntry.Id})
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@Complete", .SqlDbType = SqlDbType.Bit, .Value = newTimeEntry.Complete})
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@Note", .SqlDbType = SqlDbType.NVarChar, .Size = -1, .Value = newTimeEntry.Note})
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@actEndTime", .SqlDbType = SqlDbType.DateTime, .Value = newTimeEntry.actClockOutTime})
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@EndTime", .SqlDbType = SqlDbType.Decimal, .Value = newTimeEntry.ClockOutTime})
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@Hours", .SqlDbType = SqlDbType.Decimal, .Value = newTimeEntry.Hours})
con.Open()
Dim i As Integer = cmd.ExecuteNonQuery()
If (cmd.ExecuteNonQuery().Equals(1)) Then
res = True
Else
res = False
End If
con.Close()
End Using
End Using
End With
Return res
End Function
我发现了问题。在之前更新的某个时候,这一行
hasActiveTimeEntry = clsTimeTracker.GetActiveTimeEntry(user, timeEntry)
被移动到函数的末尾,它之前在调用数据库更新之前被调用。更新查询将垃圾传递给 TimeEntryID 并且正在更新另一行。
更新按钮点击代码
Private Sub btnStop_Click(sender As Object, e As EventArgs) Handles btnStop.Click
Timer.Stop()
Dim hasActiveTimeEntry As Boolean
hasActiveTimeEntry = clsTimeTracker.GetActiveTimeEntry(user, timeEntry)
clsTimeTracker.EndTimeEntry(timeEntry)
ClearActiveTimeEntryDisplay()
RefreshActiveTimeEntryDisplay()
LoadCompletedTimeEntryGrid(user, timeEntryList)
LoadProjectListGrid(user, projList)
End Sub
更新的 SQL 查询代码
Public Shared Function EndTimeEntry(newTimeEntry As clsTimeEntry) As Boolean
Dim res As Boolean = False
With newTimeEntry
.actClockOutTime = DateTime.Now()
.Complete = True
Dim sqlString As String = ""
sqlString = " UPDATE TimeEntry Set Complete = @Complete, Note = @Note, actEndTime = @actEndTime, EndTime = @EndTime, Hours = @Hours where TimeEntryID = @TimeEntryID"
Using con As New SqlConnection(clsCheckDBConnection.ConnStrTimeTrackerDB)
Using cmd As New SqlCommand(sqlString, con)
cmd.CommandType = CommandType.Text
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@TimeEntryID", .SqlDbType = SqlDbType.Int, .Value = newTimeEntry.Id})
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@Complete", .SqlDbType = SqlDbType.Bit, .Value = newTimeEntry.Complete})
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@Note", .SqlDbType = SqlDbType.NVarChar, .Size = -1, .Value = newTimeEntry.Note})
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@actEndTime", .SqlDbType = SqlDbType.DateTime, .Value = newTimeEntry.actClockOutTime})
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@EndTime", .SqlDbType = SqlDbType.Decimal, .Value = newTimeEntry.ClockOutTime})
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@Hours", .SqlDbType = SqlDbType.Decimal, .Value = newTimeEntry.Hours})
con.Open()
Dim i As Integer = cmd.ExecuteNonQuery().Equals(1)
If (i) Then
res = True
Else
res = False
End If
con.Close()
End Using
End Using
End With
Return res
End Function