OleDb.ExecuteNonQuery 总是返回 0

OleDb.ExecuteNonQuery always returning 0

我调查了之前提出的此类问题,但 none 的解决方案对我有用。

我在更新 Access 数据库中的 Boolean 列时遇到问题。但查询在 Access 中工作得很好。

我已经尝试过的:

  1. SqlCommand
  2. 中直接使用TRUEFALSE
  3. 使用 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

问题 1user 是保留字

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 声明 OleDbConnectionOleDbCommand(这些对象是一次性的)。处理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