VB.NET实现.mdb到.accdb数据迁移失败:数据未保存且无报错
排查VB.NET合并DataSet后无法写入Access数据库的问题
你的代码逻辑框架没问题,但数据没写入且无报错,大概率是以下几个原因导致:
1. DataSet合并后的数据行状态未标记为待更新
DataSet.Merge() 默认不会将合并进来的行标记为 Added 或 Modified,而是保持 Unchanged 状态。DataAdapter.Update() 只会处理状态为 Added/Modified/Deleted 的行,这直接导致没有数据被写入数据库。
解决方法:
调用Merge时指定参数,强制将合并的行标记为待更新状态:
newDS.Merge(oldDS, True, MissingSchemaAction.AddWithKey)
第三个参数MissingSchemaAction.AddWithKey会确保主键信息被正确加载,Merge后重复主键的行会标记为Modified,新行会标记为Added,这样Update()就能识别并处理这些行。
如果确认新库中没有旧库的重复数据,也可以手动遍历修改行状态:
For Each row As DataRow In newDS.Tables("TABLE1").Rows row.SetAdded() Next
2. 目标表缺少主键,导致OleDbCommandBuilder无法生成有效命令
OleDbCommandBuilder 依赖表的主键信息来自动生成Insert/Update/Delete命令。如果你的TABLE1没有设置主键,builder生成的命令会无效,Update()执行时不会有任何操作,也不会抛出错误。
解决方法:
检查目标accdb数据库中的TABLE1,确保已设置主键字段。如果无法修改表结构,可以手动编写InsertCommand,替代自动生成的命令。
3. 未验证Update方法的返回值
DataAdapter.Update()会返回受影响的行数,你可以输出这个值来确认是否真的没有数据被处理:
Dim affectedRows As Integer = newDA.Update(newDS, "TABLE1") Console.WriteLine($"受影响行数: {affectedRows}")
如果返回0,说明确实没有符合更新条件的行;如果返回大于0但数据库无数据,可能是事务未提交(OleDb默认自动提交,这种情况极少)。
修改后的完整代码示例
Dim oldConn As OleDbConnection Dim OldCmd As OleDbCommand Dim OldDA As OleDbDataAdapter Dim newconn As OleDbConnection Dim newCmd As OleDbCommand Dim newDA As OleDbDataAdapter Dim oldDS As DataSet = New DataSet Dim newDS As DataSet = New DataSet Dim builder As OleDbCommandBuilder oldConn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=oldfile.mdb;") oldConn.Open() OldCmd = New OleDbCommand("SELECT * FROM TABLE1", oldConn) OldDA = New OleDbDataAdapter(OldCmd) OldDA.Fill(oldDS, "TABLE1") oldConn.Close() ' 及时关闭旧连接 newconn = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=newfile.accdb;") newconn.Open() newCmd = New OleDbCommand("SELECT * FROM TABLE1", newconn) newDA = New OleDbDataAdapter(newCmd) builder = New OleDbCommandBuilder(newDA) newDA.Fill(newDS, "TABLE1") ' 生成带主键的命令 newDA.InsertCommand = builder.GetInsertCommand(True) newDA.UpdateCommand = builder.GetUpdateCommand(True) newDA.DeleteCommand = builder.GetDeleteCommand(True) ' 合并数据并标记待更新状态 newDS.Merge(oldDS, True, MissingSchemaAction.AddWithKey) ' 执行更新并输出结果 Dim affectedRows As Integer = newDA.Update(newDS, "TABLE1") Console.WriteLine($"成功写入 {affectedRows} 条数据") newconn.Close()
内容的提问来源于stack exchange,提问作者jpi76
相关产品推荐
相关产品推荐

