OleDb.ExecuteNonQuery 总是返回 0
OleDb.ExecuteNonQuery always returning 0
我调查了之前提出的此类问题,但 none 的解决方案对我有用。
我在更新 Access 数据库中的 Boolean
列时遇到问题。但查询在 Access 中工作得很好。
我已经尝试过的:
- 在
SqlCommand
中直接使用TRUE
或FALSE
- 使用
Parameters.Add()
代替 Parameters.AddWithValue()
我的ClickEvent
:
Private Sub Update_Click(sender As Object, e As RoutedEventArgs) Handles btn_update.Click
Dim mc As New UsersModule() With {
.UserID = tbx_userid.Text,
.UserName = tbx_username.Text,
.UserPassword = tbx_password.Text,
.UserRole = combx_role.SelectedValue.ToString,
.UserFullname = tbx_fullname.Text,
.UserActive = cbx_active.IsChecked
}
Dim bridge As New UsersBridge()
If bridge.UpdateUser(mc) Then
MsgBox("User's Data Updated Successfully")
Else
MsgBox("Something went wrong :/")
End If
End Sub
我的模块class:
Public Class UsersModule
Private ID As Integer, Name As String, Pass As String, Role As String, Fullname As String, isActive As Boolean
Public Property UserID() As Integer
Get
Return ID
End Get
Protected Friend Set(value As Integer)
ID = value
End Set
End Property
Public Property UserName() As String
Get
Return Name
End Get
Protected Friend Set(value As String)
Name = value
End Set
End Property
Public Property UserPassword() As String
Get
Return Pass
End Get
Protected Friend Set(value As String)
Pass = value
End Set
End Property
Public Property UserRole() As String
Get
Return Role
End Get
Protected Friend Set(value As String)
Role = value
End Set
End Property
Public Property UserFullname() As String
Get
Return Fullname
End Get
Protected Friend Set(value As String)
Fullname = value
End Set
End Property
Public Property UserActive() As Boolean
Get
Return isActive
End Get
Protected Friend Set(value As Boolean)
isActive = value
End Set
End Property
End Class
我的桥class:
Public Class Accounts_Bridge
Shared conStr As String = Windows.Application.Current.FindResource("connectionString")
Public Function Update(mc As AccountsData) As Boolean
Dim con As New OleDb.OleDbConnection(conStr)
Dim isSuccessful As Boolean = False
Try
Dim sql As String = "UPDATE Users SET UserName = @user, UserPassword = @pass, UserRole = @role, UserFullname = @name, UserActive = @active WHERE UserID = @id"
Dim cmd As New OleDb.OleDbCommand(sql, con)
cmd.Parameters.Add("@id", OleDbType.Integer).Value = mc.UserID
cmd.Parameters.Add("@user", OleDbType.VarChar).Value = mc.UserName
cmd.Parameters.Add("@pass", OleDbType.VarChar).Value = mc.UserPassword
cmd.Parameters.Add("@role", OleDbType.VarChar).Value = mc.UserRole
cmd.Parameters.Add("@name", OleDbType.VarChar).Value = mc.UserFullname
cmd.Parameters.Add("@active", OleDbType.Boolean).Value = mc.UserActive
con.Open()
Dim i As Integer = cmd.ExecuteNonQuery() 'Always Returns 0
If i > 0 Then
isSuccessful = True
Else
isSuccessful = False
End If
Catch ex As Exception
MsgBox(ex.Message)
Finally
con.Close()
End Try
Return isSuccessful
End Function
End Class
问题 1:user
是保留字
user
是 Access/OleDB 中的 reserved word。
因此您需要将术语转义为 [user]
,以便查询将其视为列名。
问题 2:参数位置
与SQL服务器不同,Access/OleDB不使用命名参数;它们只是位置占位符。
因此,您必须在 SQL 查询中列出的 exact order 中提供参数值。
推荐
1.0 你应该 stop using AddWithValue()
这个主题在 Stack Overflow 社区中得到了高度讨论和推荐。
1.1 相反,您需要为每个参数传递 OleDbType
并确保解析的数据类型和长度必须与 table 列的类型匹配.
2.0 必须用 Using
statements 声明 OleDbConnection
和 OleDbCommand
(这些对象是一次性的)。处理Connection非常重要。
2.1成功和失败的情况下,一旦进程结束,连接将自动释放。因此,您无需在 finally
块中手动 con.Close()
。
要解决上述问题,您的代码应如下所示:
Public Function Update(mc As AccountsData) As Boolean
Using con As New OleDb.OleDbConnection(conStr)
Dim isSuccessful As Boolean = False
Try
Dim sql As String = "UPDATE Users SET UserName = @user, UserPassword = @pass, UserRole = @role, UserFullname = @name, UserActive = @active WHERE UserID = @id"
Using cmd As New OleDb.OleDbCommand(sql, con)
cmd.Parameters.Add("@user", OleDbType.VarChar).Value = mc.UserName
cmd.Parameters.Add("@pass", OleDbType.VarChar).Value = mc.UserPassword
cmd.Parameters.Add("@role", OleDbType.VarChar).Value = mc.UserRole
cmd.Parameters.Add("@name", OleDbType.VarChar).Value = mc.UserFullname
cmd.Parameters.Add("@active", OleDbType.Boolean).Value = mc.UserActive
cmd.Parameters.Add("@id", OleDbType.Integer).Value = mc.UserID
con.Open()
Dim i As Integer = cmd.ExecuteNonQuery()
If i > 0 Then
isSuccessful = True
Else
isSuccessful = False
End If
End Using
Catch ex As Exception
MsgBox(ex.Message)
End Try
Return isSuccessful
End Using
End Function
我调查了之前提出的此类问题,但 none 的解决方案对我有用。
我在更新 Access 数据库中的 Boolean
列时遇到问题。但查询在 Access 中工作得很好。
我已经尝试过的:
- 在
SqlCommand
中直接使用 - 使用
Parameters.Add()
代替Parameters.AddWithValue()
TRUE
或FALSE
我的ClickEvent
:
Private Sub Update_Click(sender As Object, e As RoutedEventArgs) Handles btn_update.Click
Dim mc As New UsersModule() With {
.UserID = tbx_userid.Text,
.UserName = tbx_username.Text,
.UserPassword = tbx_password.Text,
.UserRole = combx_role.SelectedValue.ToString,
.UserFullname = tbx_fullname.Text,
.UserActive = cbx_active.IsChecked
}
Dim bridge As New UsersBridge()
If bridge.UpdateUser(mc) Then
MsgBox("User's Data Updated Successfully")
Else
MsgBox("Something went wrong :/")
End If
End Sub
我的模块class:
Public Class UsersModule
Private ID As Integer, Name As String, Pass As String, Role As String, Fullname As String, isActive As Boolean
Public Property UserID() As Integer
Get
Return ID
End Get
Protected Friend Set(value As Integer)
ID = value
End Set
End Property
Public Property UserName() As String
Get
Return Name
End Get
Protected Friend Set(value As String)
Name = value
End Set
End Property
Public Property UserPassword() As String
Get
Return Pass
End Get
Protected Friend Set(value As String)
Pass = value
End Set
End Property
Public Property UserRole() As String
Get
Return Role
End Get
Protected Friend Set(value As String)
Role = value
End Set
End Property
Public Property UserFullname() As String
Get
Return Fullname
End Get
Protected Friend Set(value As String)
Fullname = value
End Set
End Property
Public Property UserActive() As Boolean
Get
Return isActive
End Get
Protected Friend Set(value As Boolean)
isActive = value
End Set
End Property
End Class
我的桥class:
Public Class Accounts_Bridge
Shared conStr As String = Windows.Application.Current.FindResource("connectionString")
Public Function Update(mc As AccountsData) As Boolean
Dim con As New OleDb.OleDbConnection(conStr)
Dim isSuccessful As Boolean = False
Try
Dim sql As String = "UPDATE Users SET UserName = @user, UserPassword = @pass, UserRole = @role, UserFullname = @name, UserActive = @active WHERE UserID = @id"
Dim cmd As New OleDb.OleDbCommand(sql, con)
cmd.Parameters.Add("@id", OleDbType.Integer).Value = mc.UserID
cmd.Parameters.Add("@user", OleDbType.VarChar).Value = mc.UserName
cmd.Parameters.Add("@pass", OleDbType.VarChar).Value = mc.UserPassword
cmd.Parameters.Add("@role", OleDbType.VarChar).Value = mc.UserRole
cmd.Parameters.Add("@name", OleDbType.VarChar).Value = mc.UserFullname
cmd.Parameters.Add("@active", OleDbType.Boolean).Value = mc.UserActive
con.Open()
Dim i As Integer = cmd.ExecuteNonQuery() 'Always Returns 0
If i > 0 Then
isSuccessful = True
Else
isSuccessful = False
End If
Catch ex As Exception
MsgBox(ex.Message)
Finally
con.Close()
End Try
Return isSuccessful
End Function
End Class
问题 1:user
是保留字
user
是 Access/OleDB 中的 reserved word。
因此您需要将术语转义为 [user]
,以便查询将其视为列名。
问题 2:参数位置
与SQL服务器不同,Access/OleDB不使用命名参数;它们只是位置占位符。
因此,您必须在 SQL 查询中列出的 exact order 中提供参数值。
推荐
1.0 你应该 stop using AddWithValue()
这个主题在 Stack Overflow 社区中得到了高度讨论和推荐。
1.1 相反,您需要为每个参数传递 OleDbType
并确保解析的数据类型和长度必须与 table 列的类型匹配.
2.0 必须用 Using
statements 声明 OleDbConnection
和 OleDbCommand
(这些对象是一次性的)。处理Connection非常重要。
2.1成功和失败的情况下,一旦进程结束,连接将自动释放。因此,您无需在 finally
块中手动 con.Close()
。
要解决上述问题,您的代码应如下所示:
Public Function Update(mc As AccountsData) As Boolean
Using con As New OleDb.OleDbConnection(conStr)
Dim isSuccessful As Boolean = False
Try
Dim sql As String = "UPDATE Users SET UserName = @user, UserPassword = @pass, UserRole = @role, UserFullname = @name, UserActive = @active WHERE UserID = @id"
Using cmd As New OleDb.OleDbCommand(sql, con)
cmd.Parameters.Add("@user", OleDbType.VarChar).Value = mc.UserName
cmd.Parameters.Add("@pass", OleDbType.VarChar).Value = mc.UserPassword
cmd.Parameters.Add("@role", OleDbType.VarChar).Value = mc.UserRole
cmd.Parameters.Add("@name", OleDbType.VarChar).Value = mc.UserFullname
cmd.Parameters.Add("@active", OleDbType.Boolean).Value = mc.UserActive
cmd.Parameters.Add("@id", OleDbType.Integer).Value = mc.UserID
con.Open()
Dim i As Integer = cmd.ExecuteNonQuery()
If i > 0 Then
isSuccessful = True
Else
isSuccessful = False
End If
End Using
Catch ex As Exception
MsgBox(ex.Message)
End Try
Return isSuccessful
End Using
End Function