【问题标题】:Is there any problem with this code to update database values in MS Access?此代码在 MS Access 中更新数据库值是否有任何问题?
【发布时间】:2019-07-23 12:14:55
【问题描述】:

我的表单有一个 DataGridView,如果我点击一行,行的详细信息就会放在表单上的相应控件中。然后我可以对这些控件进行一些更改,然后单击按钮更新。令人惊讶的是,该代码并未对数据库进行任何更改。我想知道,这段代码有什么问题吗?这是我的应用程序的更新按钮代码。

Private Sub UpdateButton_Click(sender As Object, e As EventArgs) Handles updateButton.Click

    Try
        Using conn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\Tukabakoma.mdb;")
            conn.Open()
            Dim cmd As New OleDbCommand("Update Members set [Name]=@name,Middlename=@midname,Surname=@sname,ContactNumber=@contnum,Address=@address,DOB=@dob,Gender=@gender,[Status]=@status,JoinDate=@jd,POB=@pob,[Guardian Name]=@guardname,[Guardian Surname]=@guardsname,Relationship=@rel,GuardNumber=@gcontnum where TKBS_ID=@tkbsid", conn)
            With cmd.Parameters
                .AddWithValue("@tkbsid", tkbsIDTextBox.Text)
                .AddWithValue("@name", nameTextBox.Text)
                .AddWithValue("@midname", middleNameTextBox.Text)
                .AddWithValue("@sname", surnameTextBox.Text)
                .AddWithValue("@contnum", contactTextBox.Text)
                .AddWithValue("@address", addressTextBox.Text)
                .AddWithValue("@jd", jdDateTimePicker.Value)
                If maleRadioButton.Checked = True Then
                    .AddWithValue("@gender", maleRadioButton.Text)
                ElseIf femaleRadioButton.Checked = True Then
                    .AddWithValue("@gender", femaleRadioButton.Text)
                End If
                .AddWithValue("@status", statusComboBox.Text)
                .AddWithValue("@dob", dobDateTimePicker.Value)
                .AddWithValue("@pob", burialPlaceTextBox.Text)
                .AddWithValue("@guardname", gNameTextBox.Text)
                .AddWithValue("@guardsname", gSurnameTextBox.Text)
                .AddWithValue("@rel", relationshipTextBox.Text)
                .AddWithValue("@gcontnum", gNumberTextBox.Text)
            End With
            cmd.ExecuteNonQuery()
            RefreshDataGridView()
            MessageBox.Show("Member information successfuly updated!", "INFO", MessageBoxButtons.OK, MessageBoxIcon.Information)
            cmd.Dispose()
            conn.Close()
        End Using

    Catch ex As Exception
        MessageBox.Show(ex.Message, "ERROR12", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try
End Sub

【问题讨论】:

  • 你的参数的顺序是关闭的。我建议使用 DataAdapter 来执行更新。
  • 正确的方法是在数据库中创建一个DataTableFill,如果合适的话,最初使用数据适配器,将其绑定到BindingSource,然后将其绑定到两者DataGridView 和其他控件。当用户在各个控件中输入数据时,它会被推送到DataTable,因此将首先反映在DataGridView 中。然后,您使用相同的数据适配器到 Update 数据库,其中包含来自 DataTable 的更改。
  • 您应该在参数适用的列之后命名您的参数,这样如果您使用了错误的值就会很明显。
  • @jmcilhinney 怎么样?我已按照建议编辑了参数。
  • 那是你研究的。这就是为什么我将其发布在评论而不是答案中。你现在所做的基本上都是错的,所以你需要回到绘图板上,学习如何以正确的方式去做。如果您这样做并且您尝试的方法不起作用,那么您可以发布一个新问题。

标签: vb.net ms-access


【解决方案1】:

这里 OleDb 和 Access 的主要思想是将参数添加到 Parameters 集合中,其顺序与它们在 Sql 语句中出现的顺序相同。

.AddWithValue("@rel", relationshipTextBox.Text).AddWithValue("@gcontnum", gNumberTextBox.Text) 不在您的更新语句中,因此无法将它们添加到参数集合中。如果您更改 Update 语句以包含这些,请确保在将它们添加到参数集合时将它们放在正确的位置。

没有必要关闭您的连接,因为End Using 行将关闭并处理它。如果您对OleDbCommand 也这样做会更好。也就是说,包含在 Using 块中。

    Dim cmd As New OleDbCommand(Dim cmd As New OleDbCommand("Update Members set 
        [Name]=@name,
        Middlename=@midname,
        Surname=@sname,
        ContactNumber=@contnum,
        Address=@address,
        DOB=@dob,
        Gender=@gender,
        [Status]=@status,
        JoinDate=@jd,
        POB=@pob,
        [Guardian Name]=@guardname,
        [Guardian Surname]=@guardsname,
        Relationship=@rel,
        GuardNumber=@gcontnum 
        where TKBS_ID=@tkbsid", conn)
    With cmd.Parameters
        .AddWithValue("@name", nameTextBox.Text)
        .AddWithValue("@midname", middleNameTextBox.Text)
        .AddWithValue("@sname", surnameTextBox.Text)
        .AddWithValue("@contnum", contactTextBox.Text)
        .AddWithValue("@address", addressTextBox.Text)
        .AddWithValue("@dob", dobDateTimePicker.Value)
        If maleRadioButton.Checked = True Then
            .AddWithValue("@gender", maleRadioButton.Text)
        ElseIf femaleRadioButton.Checked = True Then
            .AddWithValue("@gender", femaleRadioButton.Text)
        End If
        .AddWithValue("@status", statusComboBox.Text)
        .AddWithValue("@jd", jdDateTimePicker.Value)
        .AddWithValue("@pob", burialPlaceTextBox.Text)
        .AddWithValue("@guardname", gNameTextBox.Text)
        .AddWithValue("@guardsname", gSurnameTextBox.Text)
        .AddWithValue("@tkbsid", tkbsIDTextBox.Text)
    End With

我必须提到.AddWithValue 不是最好的方法。见http://www.dbdelta.com/addwithvalue-is-evil/https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/ 还有一个: https://dba.stackexchange.com/questions/195937/addwithvalue-performance-and-plan-cache-implications

首选方法是.Add(parameterName As String, OleDbType As OleDBType, Size As Integer).Value = yourValue

【讨论】:

  • 非常感谢,参数的顺序是我忽略的。重新排列参数后,我的代码现在可以完美运行。感谢您提供的链接,我从中学到了很多。但是在将 .AddWithValue 更改为使用 .Add(parameterName As String, OleDbType As OleDBType, Size As Integer).Value = yourValue 时,我的 VS 2019 说它的使用方法已经耗尽。它建议这种方法:AddWithValue(String parameterName, Object value)。请参阅 [链接] (go.microsoft.com/fwlink/?linkid=14202)。
  • 方法 .Add(ParameterName As String, Object) 已弃用。这是 .Add(ParameterName, OleDbType, Size)。首选方法类似于cmd.Parameters.Add("@name", OleDbType.VarChar, 100).Value = nameTextBox.Text。您需要检查数据库的类型和大小。您可以跳过数字的大小参数。我希望这些信息能让你接受我的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-12
  • 2019-07-28
  • 2012-04-03
相关资源
最近更新 更多