在Visual Basic 26程序中,之前可以正常工作的数据库访问代码突然抛出异常

编程语言 2026-07-09

我有一个相当复杂的VB程序,能够访问我家居控制与监控系统的各个组件,并在桌面上的窗体上显示它们的数据。启动时,它会从监控我的公用事业用电量和光伏太阳能发电的TED6000设备下载最近的数据,并将其中一些数据保存到一个使用恰当配置的数据集的Access数据库中。

为了确定实际需要从TED下载并保存哪些数据,程序会先调用一次,读取数据库中的最近数据。两天前,这个调用开始持续抛出异常。程序可执行文件在过去一个月内没有改变,除了VB程序之外,没有其他人触及数据库。

该程序多年来一直处于间歇性开发状态,但其最新版本在系统启动到关机之间稳定运行了一段多于一个月的时间。以下是导致失败的子例程的源代码,直到失败的调用:

    Friend Sub Update_DataTable(ByVal intMTU0Count As Integer, ByVal minhArray() As NewMinHistory)
        Dim dst1 As New NewEnergyDataSet
        Dim tba1 As New NewEnergyDataSetTableAdapters.qryRecentMinDataTableAdapter
        Dim tbl1 As New NewEnergyDataSet.qryRecentMinDataDataTable
        Dim rowData() As NewEnergyDataSet.qryRecentMinDataRow
        Dim rowNew As NewEnergyDataSet.qryRecentMinDataRow
        Dim intCount As Integer
        Dim intCount2 As Integer
        Dim intMTUNumber As Integer
        Dim dtTemp As Date
        Dim dtArray(2) As Date

        If intMTU0Count <= 0 Then Exit Sub ' nothing to do

        tba1.Fill(tbl1) ' This is the call that throws the exception

这是异常的堆栈跟踪:

System.Runtime.InteropServices.SEHException
  HResult=0x80004005
  Message=External component has thrown an exception.
  Source=System.Data
  StackTrace:
   at System.Data.OleDb.DataSourceWrapper.InitializeAndCreateSession(OleDbConnectionString constr, SessionWrapper& sessionWrapper)
   at System.Data.OleDb.OleDbConnectionInternal..ctor(OleDbConnectionString constr, OleDbConnection connection)
   at System.Data.OleDb.OleDbConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)
   at System.Data.ProviderBase.DbConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionInternal.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   at System.Data.OleDb.OleDbConnection.Open()
   at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)
   at ShowBuff.NewEnergyDataSetTableAdapters.qryRecentMinDataTableAdapter.Fill(qryRecentMinDataDataTable dataTable) in G:\W11Work\Documents\Visual Studio 2026\Projects\ShowBuff\ShowBuff\NewEnergyDataSet.Designer.vb:line 7549
   at ShowBuff.Access.Update_DataTable(Int32 intMTU0Count, NewMinHistory[] minhArray) in G:\W11Work\Documents\Visual Studio 2026\Projects\ShowBuff\ShowBuff\Access.vb:line 186
   at ShowBuff.GateWay.Update_Data(NewMinHistory[]& minhArray, NewHistory[]& hhArray, NewHistory[]& dhArray, Boolean blNewDay) in G:\W11Work\Documents\Visual Studio 2026\Projects\ShowBuff\ShowBuff\Gateway.vb:line 35
   at ShowBuff.Form1.Form1_Load(Object sender, EventArgs e) in G:\W11Work\Documents\Visual Studio 2026\Projects\ShowBuff\ShowBuff\Form1.vb:line 184
   at System.EventHandler.Invoke(Object sender, EventArgs e)
   at System.Windows.Forms.Form.OnLoad(EventArgs e)
   at System.Windows.Forms.Form.OnCreateControl()
   at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   at System.Windows.Forms.Control.CreateControl()
   at System.Windows.Forms.Control.WmShowWindow(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ContainerControl.WndProc(Message& m)
   at System.Windows.Forms.Form.WmShowWindow(Message& m)
   at System.Windows.Forms.Form.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

我原本以为数据库可能已经损坏,或者用于填充表格的查询因为源表变得太大而失败或超时,但在MS Access中打开数据库没有问题,查询也按预期工作,而且我也能(像平时那样、偶尔这样做地那样)把大部分记录从源表移动到备份表。

我最后对数据库进行了“压缩与修复”的处理——再次没有问题。我还升级到了VS的最新版本并重新构建程序——构建没有问题,但异常仍然发生在同一个位置。

我现在都不知道该从哪里开始排查。非常感谢任何有用的建议。

补充新增的两条信息:

  1. 进一步测试表明,任何通过数据集访问数据的尝试也会得到与原始异常类似的错误。
  2. 在Visual Studio的数据集编辑器页面对各种可能有问题的数据集组件执行“预览”时,结果是有效的——也就是说,可以看到指定的数据记录。

再补充信息:

创建一个新的.NET Framework应用程序、创建数据集,然后在默认窗体中添加一个基于数据集中的某个表的DataGridView,会产生一个最小的应用程序,运行时在尝试显示窗体时抛出相同的异常。即使数据集链接到系统中完全不同的Access数据库,也会出现这种情况。

解决方案

一个部分性的答案,其最大的优点是让应用程序重新正常工作,是遵循一些评论者的建议,将数据放在SQL Server上进行托管,而不是保留在Access数据库里。我也向Visual Studio团队提交了一个问题报告,但经验告诉我,他们像上帝的磨坊一样转得很慢!

将此数据库安装并切换到SQL Server并没有我预期的那么麻烦——在应用程序中所需的更改也并不多,现在应用程序已经恢复正常运行。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章