【问题标题】:OleDb.ExecuteNonQuery always returning 0OleDb.ExecuteNonQuery 总是返回 0
【发布时间】:2021-10-27 21:19:22
【问题描述】:

我查看了以前提出的此类问题,但没有一个解决方案对我有用。

我在更新 Access 数据库中的 Boolean 列时遇到问题。但是该查询在 Access 中运行良好。

我已经尝试过的:

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

我的模块类:

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

我的桥牌课程:

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

【问题讨论】:

  • 您是否尝试过调试您的 Bridge 类? mc 变量有值吗?
  • 是的,我确实调试了我的 Bridge 类,并且确实收到了 mc 变量中的值。 @ErrBon
  • 顺便说一下,您可以将 If i > 0 Then... End If 缩短为 isSuccessful = i > 0

标签: sql vb.net ado.net ms-access-2010 oledb


【解决方案1】:

问题1user是保留字

user 是 Access/OleDB 中的 reserved word

因此,您需要将术语转义为 [user],以便查询将其视为列名。

问题2:参数位置

与 SQL Server 不同,Access/OleDB 不使用命名参数;它们只是位置占位符。

因此,您必须在 SQL 查询中列出的exact order 中提供参数值。

建议

1.0你应该stop using AddWithValue()这个话题在Stack Overflow社区得到了高度讨论和推荐。

1.1 相反,您需要为每个参数传递OleDbType,并确保解析的数据类型和长度必须与表列的类型匹配。

2.0 必须用Using statements 声明OleDbConnectionOleDbCommand(这些对象是一次性的)。释放连接非常重要。

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

【讨论】:

  • 1) 我知道用户是访问中的保留字,因此我使用了“用户名”,实际上我复制了错误的桥接类,对此感到抱歉。 2) 正如我在帖子中所写的那样,我确实尝试了 Add() 而不是 AddWithValue()。但我仍然得到零行编辑。
  • 嗨@Cyborg,你安排好参数的顺序了吗?如上文第 2 期所述,@id 应排在最后。
  • 谢谢@YongShun。这与订单有关。我从来没有意识到传递参数时顺序很重要。感谢您的帮助
猜你喜欢
  • 2015-09-27
  • 2014-03-20
  • 2013-04-13
  • 2013-03-30
  • 2016-07-13
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 2018-02-04
相关资源
最近更新 更多