首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从VB 2015更新MS Access数据库

从VB 2015更新MS Access数据库
EN

Stack Overflow用户
提问于 2015-11-11 20:16:20
回答 3查看 1.9K关注 0票数 1

我试图从VB 2015代码中更新MS Access数据库。数据集信息不会返回到数据库。

我已经阅读了这里的答案,其中说在更新之前您不能使用AcceptChanges,但是如果将其注释掉,那么下面的da.Update(ds)就会给出:

代码语言:javascript
运行
复制
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Data.dll
Additional Information: Update requires a valid UpdateCommand when passed DataRow collection with modified rows.

数据库TestDb -一个表= TestTable -设计:

代码语言:javascript
运行
复制
Name        Type               Size
--------    -------          ------
ID          Long Integer          4 Primary Key
Name        Text                255
NumberOne   Long Integer          4
NumberTwo   Long Integer          4

内容:

TestTable

代码语言:javascript
运行
复制
ID  Name        NumberOne   NumberTwo
1   EntryOne    1   
2   EntryTwo    2   
3   EntryThree  3   
4   EntryFour   4   
5   EntryFive   5

请注意,“NumberTwo”列有意保留为空白。

程序DbTest.vb

  1. 开始时,程序将数据库加载到dataset中。可以使用<<、<、>和>>按钮逐步遍历数据。
  2. 执行按钮使用“NumberTwo”列中条目的平方填充dataset的“NumberOne”列。
  3. Save按钮尝试通过数据适配器将修改后的数据集保存回数据库。然后将数据库加载到第二个数据集中,以检查第一个数据集是否已正确保存回数据库。然后逐步遍历数据,就会发现保存失败。

我的代码:

代码语言:javascript
运行
复制
'**********
' DbTest.vb
' Version 0.00
' MDJ 2015/11/11
'**********

Imports System
Imports System.IO
Imports System.Text
Public Class Form1
    Dim conn As NewOleDb.OleDbConnection(connectionString:="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=TestDB.accdb;Persist Security Info=False;")
    Dim strSQL As String = "SELECT * FROM TestTable"
    Dim da As New OleDb.OleDbDataAdapter(strSQL, conn)
    Dim ds As New DataSet()
    Dim ds2 As New DataSet()
    Dim intCurrentIndex As Integer
    Dim dSaved As Boolean = False
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    dSaved = False
    txtError.Text = "No Exceptions"
    Try
        conn.Open()
    Catch ex As OleDb.OleDbException
        txtError.Text = "OleDbException"
        GoTo errExit
    Catch ex As DataException
        txtError.Text = "DataException"
        GoTo errExit
    Catch ex As Exception
        txtError.Text = "Other Exception"
        GoTo errExit
    End Try
    txtError.Text = "Error: ds Is Empty"
    ' Fill dataset from database
    da.Fill(ds)
    'Check if the Table is empty
    If ds.Tables(0).Rows.Count > 0 Then
        txtError.Text = "No Error"
    End If
errExit:
    conn.Close()
End Sub

Private Sub btnFirst_Click(sender As Object, e As EventArgs) Handles btnFirst.Click
    'Since 0 is the first row
    intCurrentIndex = 0
    txtID.Text = ds.Tables(0).Rows(intCurrentIndex).Item("ID").ToString()
    txtName.Text = ds.Tables(0).Rows(intCurrentIndex).Item("Name").ToString()
    txtNumberOne.Text = ds.Tables(0).Rows(intCurrentIndex).Item("NumberOne").ToString()
    txtNumberTwo.Text = ds.Tables(0).Rows(intCurrentIndex).Item("NumberTwo").ToString()
    If dSaved = True Then
        txtDaNumberTwo.Text = ds2.Tables(0).Rows(intCurrentIndex).Item("NumberTwo").ToString()
    End If
End Sub

Private Sub btnPrevious_Click(sender As Object, e As EventArgs) Handles btnPrevious.Click
    'We move back only if we're not at the first row.
    If intCurrentIndex > 0 Then
        'Subtract one from the current index.
        intCurrentIndex = intCurrentIndex - 1
        txtID.Text = ds.Tables(0).Rows(intCurrentIndex).Item("ID").ToString()
        txtName.Text = ds.Tables(0).Rows(intCurrentIndex).Item("Name").ToString()
        txtNumberOne.Text = ds.Tables(0).Rows(intCurrentIndex).Item("NumberOne").ToString()
        txtNumberTwo.Text = ds.Tables(0).Rows(intCurrentIndex).Item("NumberTwo").ToString()
        If dSaved = True Then
            txtDaNumberTwo.Text = ds2.Tables(0).Rows(intCurrentIndex).Item("NumberTwo").ToString()
        End If
    Else
        MessageBox.Show("You're already at the first record.")
    End If
End Sub

Private Sub btnNext_Click(sender As Object, e As EventArgs) Handles btnNext.Click
    'ds.Tables(0).Rows.Count - 1 is the index for the last row
    'We move forward only if we're not at the last row.
    If intCurrentIndex < ds.Tables(0).Rows.Count - 1 Then
        'Add one to the current index.
        intCurrentIndex = intCurrentIndex + 1
        txtID.Text = ds.Tables(0).Rows(intCurrentIndex).Item("ID").ToString()
        txtName.Text = ds.Tables(0).Rows(intCurrentIndex).Item("Name").ToString()
        txtNumberOne.Text = ds.Tables(0).Rows(intCurrentIndex).Item("NumberOne").ToString()
        txtNumberTwo.Text = ds.Tables(0).Rows(intCurrentIndex).Item("NumberTwo").ToString()
        If dSaved = True Then
            txtDaNumberTwo.Text = ds2.Tables(0).Rows(intCurrentIndex).Item("NumberTwo").ToString()
        End If
    Else
        MessageBox.Show("You're already at the last record.")
    End If
End Sub

Private Sub btnLast_Click(sender As Object, e As EventArgs) Handles btnLast.Click
    'ds.Tables(0).Rows.Count - 1 is the index for the last row
    intCurrentIndex = ds.Tables(0).Rows.Count - 1
    txtID.Text = ds.Tables(0).Rows(intCurrentIndex).Item("ID").ToString()
    txtName.Text = ds.Tables(0).Rows(intCurrentIndex).Item("Name").ToString()
    txtNumberOne.Text = ds.Tables(0).Rows(intCurrentIndex).Item("NumberOne").ToString()
    txtNumberTwo.Text = ds.Tables(0).Rows(intCurrentIndex).Item("NumberTwo").ToString()
    If dSaved = True Then
        txtDaNumberTwo.Text = ds2.Tables(0).Rows(intCurrentIndex).Item("NumberTwo").ToString()
    End If
End Sub

Private Sub btnExecute_Click(sender As Object, e As EventArgs) Handles btnExecute.Click
    Dim n1 As Integer
    Dim n2 As Integer
    'ds.Tables(0).Rows.Count - 1 is the index for the last row
    Dim intLastCount As Integer
    intLastCount = ds.Tables(0).Rows.Count - 1
    ' Process each record
    For intCurrentIndex = 0 To intLastCount
        n1 = ds.Tables(0).Rows(intCurrentIndex).Item("NumberOne")
        n2 = n1 * n1
        ds.Tables(0).Rows(intCurrentIndex).Item("NumberTwo") = n2
    Next
    ' If this is commented out, then da.Update(ds) below gives:
    '   An unhandled exception of type 'System.InvalidOperationException' occurred in System.Data.dll
    '   Additional Information: Update requires a valid UpdateCommand when passed DataRow collection with modified rows.
    ds.AcceptChanges()
End Sub

Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
    txtError.Text = "No Exceptions"
    Try
        conn.Open()
    Catch ex As OleDb.OleDbException
        txtError.Text = "OleDbException"
        GoTo errExit
    Catch ex As DataException
        txtError.Text = "DataException"
        GoTo errExit
    Catch ex As Exception
        txtError.Text = "Other Exception"
        GoTo errExit
    End Try

ERRLOC:
    ' THE PROBLEM IS HERE
    '   The dataset is not being updated back to the data adapter

    ' Save dataset to database
    da.Update(ds)
ENDERR:

    ' Fill second dataset from database
    txtError.Text = "Error: ds2 Is Empty"
    da.Fill(ds2)
    'Check if the Table is empty
    If ds2.Tables(0).Rows.Count > 0 Then
        dSaved = True
        txtError.Text = "ds2: No Error"
    End If
errExit:
    conn.Close()
End Sub
End Class

我在这里错过了什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-11-12 00:27:23

当传递带有修改行的DataRow集合时,Update需要一个有效的DataRow。

错误消息告诉您,OleDbDataAdapter没有为它定义一个UpdateCommand。定义InsertCommand、UpdateCommand和DeleteCommand属性的最常用方法可能是使用OleDbCommandBuilder对象。例如

代码语言:javascript
运行
复制
Dim da As New OleDb.OleDbDataAdapter(strSQL, conn)
Dim cb As New OleDbCommandBuilder(da)
cb.QuotePrefix = "["
cb.QuoteSuffix = "]"
票数 0
EN

Stack Overflow用户

发布于 2015-11-12 14:55:21

对于那些可能遇到类似问题的人,正确和有效的代码张贴在下面。

数据库TestDb位于本地\bin\Debug文件夹中。

Form1是主要的,也是唯一的形式。

Form1 1的设备包括:

代码语言:javascript
运行
复制
Five Label – TextBox combinations, arranged in a vertical column
Label1 Text = “ID” – TextBox Name = “txtID”
Label2 Text = “Name” – TextBox Name = “txtName”
Label3 Text = “NumberOne” – TextBox Name = “txtNumberOne”
Label4 Text = “NumberTwo” – TextBox Name = “txtNumberTwo”
Label5 Text = “da’s NumberTwo” – TextBox Name = “txtDaNumberTwo”

(Label4 – TextBox refers to the value in the DataSet)
(Label5 – TextBox refers to the value in the database)

Four buttons, side-by-side
btnFirst – Text = “<<”
btnPrevious – Text = “<”
btnNext – Text = “>”
btnLast – Text = “>>”

Two buttons, one above the other
btnExecute – Text = “Execute”
btnSave – Text = “Save”

One Label – TextBox combination
Label6 Text = “Error” – TextBox Name = “txtError”

正确和有效的代码:

代码语言:javascript
运行
复制
'**********
' DbTest.vb
' Version 0.00
' MDJ 2015/11/11
'**********

Imports System
Imports System.IO
Imports System.Text
Imports System.Data
Imports System.Data.OleDb
Public Class Form1
' This is the connection to the local MS Access database.
' The database is needed in both the Debug and Release folders.
Dim conn As New OleDb.OleDbConnection(connectionString:="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=TestDB.accdb;Persist Security Info=False;")
Dim strSQL As String = "SELECT * FROM TestTable"
' The DataAdapter is the bridge between the database and the DataSet. 
Dim da As New OleDb.OleDbDataAdapter(strSQL, conn)
' MUST INCLUDE:
' OleDbCommandBuilder statement is required for Insert, Update, and Delete
' as are the cb.Quote... statements below.
Dim cb As New OleDbCommandBuilder(da)
' The DataSet is the internal working copy of the portion of the database which is being processed.
' More than one dataset may be open at any given time.
Dim ds As New DataSet()
Dim ds2 As New DataSet()
Dim intCurrentIndex As Integer
Dim dSaved As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    cb.QuotePrefix = "["
    cb.QuoteSuffix = "]"
    dSaved = False
    txtError.Text = "No Exceptions"
    Try
        conn.Open()
    Catch ex As OleDb.OleDbException
        txtError.Text = "OleDbException"
        GoTo errExit
    Catch ex As DataException
        txtError.Text = "DataException"
        GoTo errExit
    Catch ex As Exception
        txtError.Text = "Other Exception"
        GoTo errExit
    End Try
    txtError.Text = "Error: ds Is Empty"
    ' Fill dataset from database
    da.Fill(ds)
    'Check if the Table is empty
    If ds.Tables(0).Rows.Count > 0 Then
        txtError.Text = "No Error"
    End If
errExit:
    conn.Close()
End Sub

Private Sub btnFirst_Click(sender As Object, e As EventArgs) Handles btnFirst.Click
    'Since 0 is the first row
    intCurrentIndex = 0
    txtID.Text = ds.Tables(0).Rows(intCurrentIndex).Item("ID").ToString()
    txtName.Text = ds.Tables(0).Rows(intCurrentIndex).Item("Name").ToString()
    txtNumberOne.Text = ds.Tables(0).Rows(intCurrentIndex).Item("NumberOne").ToString()
    txtNumberTwo.Text = ds.Tables(0).Rows(intCurrentIndex).Item("NumberTwo").ToString()
    If dSaved = True Then
        txtDaNumberTwo.Text = ds2.Tables(0).Rows(intCurrentIndex).Item("NumberTwo").ToString()
    End If
End Sub

Private Sub btnPrevious_Click(sender As Object, e As EventArgs) Handles btnPrevious.Click
    'We move back only if we're not at the first row.
    If intCurrentIndex > 0 Then
        'Subtract one from the current index.
        intCurrentIndex = intCurrentIndex - 1
        txtID.Text = ds.Tables(0).Rows(intCurrentIndex).Item("ID").ToString()
        txtName.Text = ds.Tables(0).Rows(intCurrentIndex).Item("Name").ToString()
        txtNumberOne.Text = ds.Tables(0).Rows(intCurrentIndex).Item("NumberOne").ToString()
        txtNumberTwo.Text = ds.Tables(0).Rows(intCurrentIndex).Item("NumberTwo").ToString()
        If dSaved = True Then
            txtDaNumberTwo.Text = ds2.Tables(0).Rows(intCurrentIndex).Item("NumberTwo").ToString()
        End If
    Else
        MessageBox.Show("You're already at the first record.")
    End If
End Sub

Private Sub btnNext_Click(sender As Object, e As EventArgs) Handles btnNext.Click
    'ds.Tables(0).Rows.Count - 1 is the index for the last row
    'We move forward only if we're not at the last row.
    If intCurrentIndex < ds.Tables(0).Rows.Count - 1 Then
        'Add one to the current index.
        intCurrentIndex = intCurrentIndex + 1
        txtID.Text = ds.Tables(0).Rows(intCurrentIndex).Item("ID").ToString()
        txtName.Text = ds.Tables(0).Rows(intCurrentIndex).Item("Name").ToString()
        txtNumberOne.Text = ds.Tables(0).Rows(intCurrentIndex).Item("NumberOne").ToString()
        txtNumberTwo.Text = ds.Tables(0).Rows(intCurrentIndex).Item("NumberTwo").ToString()
        If dSaved = True Then
            txtDaNumberTwo.Text = ds2.Tables(0).Rows(intCurrentIndex).Item("NumberTwo").ToString()
        End If
    Else
        MessageBox.Show("You're already at the last record.")
    End If
End Sub

Private Sub btnLast_Click(sender As Object, e As EventArgs) Handles btnLast.Click
    'ds.Tables(0).Rows.Count - 1 is the index for the last row
    intCurrentIndex = ds.Tables(0).Rows.Count - 1
    txtID.Text = ds.Tables(0).Rows(intCurrentIndex).Item("ID").ToString()
    txtName.Text = ds.Tables(0).Rows(intCurrentIndex).Item("Name").ToString()
    txtNumberOne.Text = ds.Tables(0).Rows(intCurrentIndex).Item("NumberOne").ToString()
    txtNumberTwo.Text = ds.Tables(0).Rows(intCurrentIndex).Item("NumberTwo").ToString()
    If dSaved = True Then
        txtDaNumberTwo.Text = ds2.Tables(0).Rows(intCurrentIndex).Item("NumberTwo").ToString()
    End If
End Sub

Private Sub btnExecute_Click(sender As Object, e As EventArgs) Handles btnExecute.Click
    Dim n1 As Integer
    Dim n2 As Integer
    'ds.Tables(0).Rows.Count - 1 is the index for the last row
    Dim intLastCount As Integer
    intLastCount = ds.Tables(0).Rows.Count - 1
    ' Process each record
    For intCurrentIndex = 0 To intLastCount
        n1 = ds.Tables(0).Rows(intCurrentIndex).Item("NumberOne")
        n2 = n1 * n1
        ds.Tables(0).Rows(intCurrentIndex).Item("NumberTwo") = n2
    Next
    ' MUST NOT DO THIS BEFORE UPDATING - IT LOSES ALL CHANGES
    'ds.AcceptChanges()
End Sub

Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
    txtError.Text = "No Exceptions"
    Try
        conn.Open()
    Catch ex As OleDb.OleDbException
        txtError.Text = "OleDbException"
        GoTo errExit
    Catch ex As DataException
        txtError.Text = "DataException"
        GoTo errExit
    Catch ex As Exception
        txtError.Text = "Other Exception"
        GoTo errExit
    End Try

    ' Save dataset to database
    Try
        da.Update(ds)
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try

    ' Fill second dataset from database
    txtError.Text = "Error: ds2 Is Empty"
    da.Fill(ds2)
    'Check if the Table is empty
    If ds2.Tables(0).Rows.Count > 0 Then
        dSaved = True
        txtError.Text = "ds2: No Error"
    End If
errExit:
    conn.Close()
End Sub
End Class
票数 0
EN

Stack Overflow用户

发布于 2017-01-25 23:04:57

我今天发现,它可能实际上并不是在更新您认为应该更新的数据库。如果在编程时从Visual运行程序,请查看bin文件夹,它在其中粘贴可执行文件,并查看它放置的db文件。

MS关于更新工作的说明:Miscrosoft指令

如果您进入每个表的DataSet TableAdapter配置,VS还可以自动生成db的插入、删除和更新命令。

必须为要使用UPDATE或DELETE的每个表设置主键。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33659058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档