使用 vb.net、oledbdataadapter 更新数据库时出现问题
Posted
技术标签:
【中文标题】使用 vb.net、oledbdataadapter 更新数据库时出现问题【英文标题】:Problems updating a database using vb.net, oledbdataadapter 【发布时间】:2020-01-27 20:21:51 【问题描述】:在查看 *** 和其他板上的多个问题/答案后,我仍然不知道为什么我不能从数据表更新 Access 数据库。我正在尝试从数据表中获取数据,如果它是空白的,则将该数据插入到 Access 表中,如果它已经有数据,则替换该表。我可以成功替换表,但数据表中的数据没有被添加。
但是,我使用的方法似乎不起作用。我的数据表来自绑定的数据网格源,访问层的调用方式如下:
ConnectedDB.UpdateTable(DBTable, bsDataSource.DataSource)
其中ConnectedDB
是Access Layer类,DBTable
是包含Access表名的字符串,bsDataSource
是绑定数据。如您所见,我通过.Datasource
将其转换为数据表。
这是我将数据表添加回 Access 表的原始(1 月 29 日之前)部分:
Public Function UpdateTable(strTable As String, dgDataTable As DataTable) As Boolean
Dim DS As New DataSet
dgDataTable.TableName = strTable
DS.Tables.Add(dgDataTable)
Using OpenCon = New OleDb.OleDbConnection(strConnectionString)
Using DataAdapter As New OleDbDataAdapter("SELECT * FROM " & strTable, OpenCon)
Dim DBcmd As OleDbCommandBuilder = New OleDbCommandBuilder(DataAdapter)
DBcmd.QuotePrefix = "["
DBcmd.QuoteSuffix = "]"
DataAdapter.UpdateCommand = DBcmd.GetUpdateCommand()
Try
OpenCon.Open()
DataAdapter.Fill(DS.Tables(strTable))
If DataAdapter.Update(DS.Tables(strTable)) > 0 Then
Return True
Else Return False
End If
Catch exo As Exception
MessageBox.Show(exo.Message)
Return False
End Try
End Using
End Using
End Function
我的函数尝试使用来自数据网格视图的数据表dgDataTable
中的信息更新名称为strTable
的现有Access 表。每次运行都会命中更新检查 > 0 并返回 false,这意味着它应该在语法上正常工作(即没有错误消息)。我已经跟踪了该表,它具有它应该具有的所有数据(因此信息通过更新命令从网格正确传递)。我正在尝试将它应用到数据集中,但我不确定我是否真的需要它。
我正在通过更新方法跟踪变量,我想我发现了它为什么不会更新,但我不知道该怎么做。它提出的查询是这样的:
UPDATE [RtoC] SET [R] = ?, [C] = ?, [Type] = ?, [Unknown] = ? WHERE (([R] = ?) AND ([C] = ?) AND ([Type] = ?) AND ((? = 1 AND [Unknown] IS NULL) OR ([Unknown] = ?)))
Access 表名为 RtoC,包含字段 R、C、Type 和 unknown。 我在想“?”没有填写,导致查询只是不将数据应用回 Access。我不确定如何设置这些项目。
编辑 1/29/20:我使用了下面的代码更改和 jmcihinney 文档,它确实将这些行插入到 Access 表中。此编辑将问题更改为更具体地说明我正在尝试做什么以及如何创建数据表。希望这可以澄清我的一些措辞,并为更改行状态提供一些基础。
【问题讨论】:
它(对我来说)看起来像这一行:DataAdapter.Fill(DS.Tables(strTable))
将擦除表的内容,在下一行,您只需尝试使用未更改的数据表进行更新。在您执行 DataAdapter.Fill()
之前和之后设置一个断点,看看您的 tablecount 或 rowcount 是否证实了我所说的。
澄清一下:当我说“擦除内容”时,我的意思是你重写了你传入这个函数并在第 2 行添加到 DataSet 的 DataTable。
我有完全相同的想法,所以我将其追溯到更新及以后。它保留了我最初放入其中的数据,这可能意味着某些东西可能无法正确触发,这就是我开始跟踪适配器查询以查看原因的原因。
连接字符串能否允许连接打开文件但阻止查询与数据库交互?我所做的更改之一是从 Jet 迁移到 ACE(4.0 到 12.0)。
【参考方案1】:
问题是该数据适配器的Fill
方法在填充DataTable
后调用AcceptChanges
,因此调用Update
时没有要保存的更改。
无论如何,对Fill
的调用不应该存在,因为您不想检索任何数据,只需保存更改即可。你那里有很多毫无意义的代码。它应该看起来更像这样:
Public Function UpdateTable(strTable As String, dgDataTable As DataTable) As Boolean
Using DataAdapter As New OleDbDataAdapter("SELECT * FROM " & strTable, strConnectionString)
Dim DBcmd As OleDbCommandBuilder = New OleDbCommandBuilder(DataAdapter)
DBcmd.QuotePrefix = "["
DBcmd.QuoteSuffix = "]"
Try
Return DataAdapter.Update(dgDataTable) > 0
Catch exo As Exception
MessageBox.Show(exo.Message)
Return False
End Try
End Using
End Function
【讨论】:
还是不行。我同意当我尝试不同的数据集/表方法时,我应该删除一些零碎的东西。有趣的是,即使它是fill
的主题,数据表也从未真正改变过。根据我的理解,您认为它至少会根据数据库中的信息改变自己。【参考方案2】:
我在操作数据库方面采取了另一种策略,在查找该数据库时,我找到了 jmcilhinney 在 2014 年提供的答案! [Bulk Insert From DataTable to Access Database
在我的数据表行的for each
循环中,我设置了这个:
row.SetAdded()
如果我正在填充,我会执行以下操作:
DataAdapter.AcceptChangesDuringFill = True
在Fill
命令之前。
除非这个方法变了或者有更好的方法,否则我会把链接标记为答案。
谢谢 jmcilhinney....两次!
【讨论】:
这带来了许多问题。现在似乎您想插入记录,而您的原始问题表明您想更新。它是哪一个?其次,如果您要向DataTable
添加记录,那么默认情况下它们的RowState
应该是Added
,因此您必须采取一些措施来改变它。最明显的原因是您在某处致电AcceptChanges
。我有兴趣了解有关此数据生命周期的更多详细信息。如果您有兴趣找到问题的根源,而不是使用解决方法,您可以更新您的问题。
你是对的,我可能在“更新”中使用了错误的词。本质上,我将数据表插入到空白 Access 表中,或者在有数据的情况下,将值更新为新的集合。我还将稍微改变问题以显示数据表的调用者。以上是关于使用 vb.net、oledbdataadapter 更新数据库时出现问题的主要内容,如果未能解决你的问题,请参考以下文章
使用 Jet 的 OleDbDataAdapter 数据类型不匹配
如何将准备好的语句与 OleDbDataAdapter 一起使用?
如何使用 oleDbDataAdapter.Update(myDataSet) 更新 excel 文件
OleDbDataAdapter 在使用包含 Join 的语句时抛出 AccessViolationException