当前位置:编程学习 > C#/ASP.NET >>

winform程序,mdb压缩完后,重新打开连接时报:System.Data.OleDb.OleDbException (0x80004005): 未指定的错误

winform程序,采用access2003格式数据库,用于记录设备运行状态,程序会自动清理压缩数据库,以保证性能。

 程序启动后,运行一段时间是正常的,但运行一段时间在压缩(通过引用Microsoft Jet and Replication Objects 2.6 Library COM组件)完数据库后,重新打开数据库时报错:
System.Data.OleDb.OleDbException (0x80004005): 未指定的错。之后数据库一直连接不上,除非重新启动程序,重新启动程序后又能正常运行一段时间,之后重复出现上述问题。

 我查了很久没有找到问题原因,程序拿到不同机器上跑都是一样的现象。我在网上也查了原因,网上都是针对asp.net的,没有针对windorm的。关于临时文件夹和程序启动目录权限问题我也试过了,没用。

 恳请大家指教,下面是我的简化之后的代码:
Imports System.Data.OleDb
Imports System.Data.Common
Imports System.Data
Imports System.IO

Public Class Form1
    Public WithEvents m_Timer As New System.Windows.Forms.Timer
    Public isDoingFlag As Boolean

    Private m_conn As OleDbConnection = Nothing
    Private m_cmd As OleDbCommand = Nothing

    Private strTmpFile As String = Application.StartupPath.TrimEnd("\".ToCharArray()) & "\Monitor.mdb"
    Private strTmpFile As String = Application.StartupPath.TrimEnd("\".ToCharArray()) & "\tmpMonitor.mdb"

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        m_conn = New OleDbConnection(DB_ConnectionString)
        m_cmd = m_conn.CreateCommand()
        m_cmd.CommandType = CommandType.Text

        m_Timer.Interval = 10
        m_Timer.Start()
    End Sub

    Private Sub Form1_FormClosing(sender As System.Object, e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        If m_Timer IsNot Nothing Then
            m_Timer.Stop()
            m_Timer.Dispose()
            m_Timer = Nothing
        End If
    End Sub

    Private Sub m_Timer_Tick(sender As Object, e As System.EventArgs) Handles m_Timer.Tick
        m_Timer.Stop()
        If isDoingFlag Then Exit Sub
        isDoingFlag = True
        Dim InsertCount As Integer = 0
        Try
            Debug.WriteLine("1次启动50次插入...")
            m_conn.Open()
            Do
                InsertCount += 1
                If InsertCount >= 50 Then Exit Do
                If m_conn IsNot Nothing Then
                    m_cmd.CommandText = "insert into t_StateLog ([DeviceCode],[StateID],[StateData],[TriggerTime]) values ('ST'," & CleanDB_dp.Id.ToString() & ",False" & ",'" & getdate() & "')"
                    m_cmd.ExecuteNonQuery()
                    Application.DoEvents()
                End If
            Loop
            Debug.WriteLine("1次插入50次完成")

            m_conn.Close()

            Compact_DB(dbfile)

            Debug.WriteLine("2次启动100次插入...")
            InsertCount = 0
            m_conn.Open()   '<----通常在这里出错:System.Data.OleDb.OleDbException (0x80004005): 未指定的错
            Do
                InsertCount += 1
                If InsertCount >= 100 Then Exit Do
                If m_conn IsNot Nothing Then
                    m_cmd.CommandText = "insert into t_StateLog ([DeviceCode],[StateID],[StateData],[TriggerTime]) values ('ST',0,False,'2013-08-16 09:50:31.894')"
                    m_cmd.ExecuteNonQuery()
                    Application.DoEvents()
                End If
            Loop
            Debug.WriteLine("2次插入100次完成" & vbCrLf)
        Catch ex As Exception
            Debug.WriteLine("清理数据库出错了!")
        Finally
            If m_conn IsNot Nothing Then m_conn.Close()
            isDoingFlag = False
            m_Timer.Start()
        End Try
    End Sub

    Private Function Compact_DB(ByVal filename As String) As Boolean
        Try
            If System.IO.File.Exists(strTmpFile) Then System.IO.File.Delete(strTmpFile)
            Debug.WriteLine("压缩数据库...")
            Dim Jet_Engine As JRO.JetEngine = New JRO.JetEngine()
            Jet_Engine.CompactDatabase("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filename + ";Jet OLEDB:Database Password=mysql;Jet OLEDB:Engine Type=5", _
                                       "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strTmpFile + ";Jet OLEDB:Database Password=mysql;Jet OLEDB:Engine Type=5")
            Jet_Engine = Nothing
            System.IO.File.Delete(filename)
            System.IO.File.Move(strTmpFile, filename)
            Debug.WriteLine("压缩数据库完成了")
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function
End Class 未指定的错误 access compactdatabase --------------------编程问答-------------------- 首先看下压缩清理后,有没有完全释放access文件的控制占用。
再看下m_conn.open之前,m_conn.state是什么 --------------------编程问答-------------------- 首先在程序启动运行一段时间内一切都正常。跑一会儿(时间不一)才报错。

其次压缩是成功的,压缩后的tmpMonitor.mdb也已经改成Monitor.mdb了,文件没有被锁定,重新打开连接前,m_conn.state是关闭状态。

重新打开失败后,下一轮再次压缩也会失败,后面对数据库的所有操作都失败,除非重启程序。

有兴趣的朋友可把这段代码拷下来跑一下就知道了。 --------------------编程问答-------------------- 把Compact_DB函数中的的删除文件和改名这两句改成下面这样试下:
While True
  Try
    System.IO.File.Delete(filename)
    System.IO.File.Move(strTmpFile, filename)
    Exit While
  Catch ex As Exception
    Debug.WriteLine(ex)
  End Try
End While
--------------------编程问答-------------------- 试过了没有效果。
压缩万数据库后,删除旧mdb,把压缩后的临时文件改名过程都没出错。
--------------------编程问答-------------------- 压缩万数据库后,删除旧mdb,把压缩后的临时文件改名过程都没出错。就是重新打开连接时出错。 --------------------编程问答-------------------- 别压缩了,换SQL SERVER吧
补充:.NET技术 ,  VB.NET
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,