【问题标题】:Unable to decrypt Microsoft Access *.mdb database with user security无法使用用户安全解密 Microsoft Access *.mdb 数据库
【发布时间】:2014-03-12 23:24:43
【问题描述】:

我有旧的 .mdb 数据库,其中包含大量表/表单/查询和外部连接(在 Access 2003 中创建),具有用户级安全性。

现在我决定迁移到 SQL Server,但我无法解密数据库(在 Access 2010 和 2013 中)以与 Access to SQL 工具一起使用。

解密过程正在运行,但最后我收到错误消息:“您无法访问此表”。

我尝试过修复和压缩。

你能帮帮我吗?

谢谢。

【问题讨论】:

    标签: sql-server ms-access


    【解决方案1】:

    据我所知,你没有太多选择:

    • 您可以通过创建新数据库并使用与原始用户完全相同的用户名和 PID 来重建 .mdw 文件,然后将新的 .mdw 与旧数据库一起使用。
      您可以使用一些the tools from Serge Gavrilov 来帮助您从数据库中查找用户名和PID。

    • 查看UtterAccess.com 上的论坛。似乎有很多关于 lost mdw 的讨论。

    • 您可以使用一些数据修复服务,例如EverythingAccess。花费一些钱,但我相信他们可以恢复您的数据。

    一旦您可以访问数据库,您就可以编写代码以从数据库中提取所有表单、查询等。这是我编写的用于执行此操作的代码的 sn-p。您将需要对其进行大量调整,因为它基于允许您选择数据库名称的表单。您将不得不对查询、表单等重复此操作...

    ' Database.
    Dim dbRep As DAO.Database
    Dim dbNew As DAO.Database
    
    ' For copying tables and indexes.
    Dim tblRep As DAO.TableDef
    Dim tblNew As DAO.TableDef
    Dim fldRep As DAO.Field
    Dim fldNew As DAO.Field
    Dim idxRep As DAO.Index
    Dim idxNew As DAO.Index
    
    ' For copying data.
    Dim rstRep As DAO.Recordset
    Dim rstNew As DAO.Recordset
    Dim rec1 As DAO.Recordset
    Dim rec2 As Recordset
    Dim intC As Integer
    
    ' For copying table relationships.
    Dim relRep As DAO.Relation
    Dim relNew As DAO.Relation
    
    ' For copying queries.
    Dim qryRep As DAO.QueryDef
    Dim qryNew As DAO.QueryDef
    
    ' For copying startup options.
    Dim avarSUOpt
    Dim strSUOpt As String
    Dim varValue
    Dim varType
    Dim prpRep As DAO.Property
    Dim prpNew As DAO.Property
    ' For importing forms, reports, modules, and macros.
    Dim appNew As New Access.Application
    Dim doc As DAO.Document
    
    ' Open the database, not in exclusive mode.
    Set dbRep = OpenDatabase(Forms!CMDB_frmUpgrade.TxtDatabase, False)
    
    
    ' Open the new database
    Set dbNew = CurrentDb
    
    DoEvents
    
    ' Turn on the hourglass.
    DoCmd.Hourglass True
    
        '********************
        Debug.Print "Copy Tables"
        '********************
    If Forms!CMDB_frmUpgrade.CkTables = True Then
        Forms!CMDB_frmUpgrade.LstMessages.addItem "Copying Tables:"
    
        ' Loop through the collection of table definitions.
        For Each tblRep In dbRep.TableDefs
        Set rec1 = dbRep.OpenRecordset("SELECT MSysObjects.Name FROM MsysObjects WHERE ([Name] = '" & tblRep.Name & "') AND ((MSysObjects.Type)=4 or (MSysObjects.Type)=6)")
    
        If rec1.EOF Then
          XF = 0
        Else
          XF = 1
        End If
    
            ' Ignore system tables and CMDB tables.
            If InStr(1, tblRep.Name, "MSys", vbTextCompare) = 0 And _
                InStr(1, tblRep.Name, "CMDB", vbTextCompare) = 0 And _
                XF = 0 Then
    
                '***** Table definition
                ' Create a table definition with the same name.
                Set tblNew = dbNew.CreateTableDef(tblRep.Name)
                Forms!CMDB_frmUpgrade.LstMessages.addItem "--> " & tblRep.Name & ""
    
                ' Set properties.
                tblNew.ValidationRule = tblRep.ValidationRule
                tblNew.ValidationText = tblRep.ValidationText
    
                ' Loop through the collection of fields in the table.
                For Each fldRep In tblRep.Fields
    
                    ' Ignore replication-related fields:
                    ' Gen_XXX, s_ColLineage, s_Generation, s_GUID, s_Lineage
                    If InStr(1, fldRep.Name, "s_", vbTextCompare) = 0 And _
                        InStr(1, fldRep.Name, "Gen_", vbTextCompare) = 0 Then
    
                        '***** Field definition
                        Set fldNew = tblNew.CreateField(fldRep.Name, fldRep.Type, _
                            fldRep.Size)
    
                        ' Set properties.
                        On Error Resume Next
                        fldNew.Attributes = fldRep.Attributes
                        fldNew.AllowZeroLength = fldRep.AllowZeroLength
                        fldNew.DefaultValue = fldRep.DefaultValue
                        fldNew.Required = fldRep.Required
                        fldNew.Size = fldRep.Size
    
                        ' Append the field.
                        tblNew.Fields.Append fldNew
                        'On Error GoTo Err_NewShell
                    End If
                Next fldRep
    
                '***** Index definition
    
                ' Loop through the collection of indexes.
                For Each idxRep In tblRep.Indexes
    
                    ' Ignore replication-related indexes:
                    ' s_Generation, s_GUID
                    If InStr(1, idxRep.Name, "s_", vbTextCompare) = 0 Then
    
                        ' Ignore indices set as part of Relation Objects
                        If Not idxRep.Foreign Then
    
                            ' Create an index with the same name.
                            Set idxNew = tblNew.CreateIndex(idxRep.Name)
    
                            ' Set properties.
                            idxNew.Clustered = idxRep.Clustered
                            idxNew.IgnoreNulls = idxRep.IgnoreNulls
                            idxNew.Primary = idxRep.Primary
                            idxNew.Required = idxRep.Required
                            idxNew.Unique = idxRep.Unique
    
                            ' Loop through the collection of index fields.
                            For Each fldRep In idxRep.Fields
                                ' Create an index field with the same name.
                                Set fldNew = idxNew.CreateField(fldRep.Name)
                                ' Set properties.
                                fldNew.Attributes = fldRep.Attributes
                                ' Append the index field.
                                idxNew.Fields.Append fldNew
                            Next fldRep
    
                            ' Append the index to the table.
                            tblNew.Indexes.Append idxNew
                        End If
                    End If
                Next idxRep
    
                ' Append the table.
                dbNew.TableDefs.Append tblNew
            End If
            DoEvents
        Next tblRep
    
        '********************
        Debug.Print "Copy Data"
        '********************
        ' Loop through the list of table definitions.
        For Each tblRep In dbRep.TableDefs
        Set rec1 = dbRep.OpenRecordset("SELECT MSysObjects.Name FROM MsysObjects WHERE ([Name] = '" & tblRep.Name & "') AND ((MSysObjects.Type)=4 or (MSysObjects.Type)=6)")
    
        If rec1.EOF Then
          XF = 0
        Else
          XF = 1
        End If
    
            ' Ignore system tables and CMDB tables.
            If InStr(1, tblRep.Name, "MSys", vbTextCompare) = 0 And _
                InStr(1, tblRep.Name, "CMDB", vbTextCompare) = 0 And _
                XF = 0 Then
    
                ' Open a recordset for the new table.
                Set rstNew = dbNew.OpenRecordset(tblRep.Name, dbOpenTable)
                ' Open a recordset for the old table.
                Set rstRep = dbRep.OpenRecordset(tblRep.Name, dbOpenTable)
    
                ' Continue if there are records.
                If Not rstRep.BOF Then
    
                    ' Move to the first record.
                    rstRep.MoveFirst
    
                    ' Loop through all the old table records.
                    Do Until rstRep.EOF
                        ' Add a record to the new table.
                        rstNew.AddNew
                        ' For each field in the new table, set the value
                        ' to the value in the related field of the old table.
                        For intC = 0 To rstNew.Fields.count - 1
                            rstNew.Fields(intC).Value = _
                                rstRep.Fields(rstNew.Fields(intC).Name).Value
                        Next
                        ' Update the new table.
                        rstNew.Update
                        ' Move to the next old table record.
                        rstRep.MoveNext
                    Loop ' rstRep
                End If
    
                ' Close the new recordset.
                rstNew.Close
                ' Close the old recordset.
                rstRep.Close
            End If
        DoEvents
        Next tblRep
    
    End If
    

    【讨论】:

    • 我可以访问我的旧数据库,但仅限于解密过程之前。我想使用 MSSQL Server 迁移工具进行访问,而不是复制粘贴方法。
    • 如果您无法解密数据库,您唯一的机会就是如上所述对数据进行后门。我什至不能保证这会奏效。 SQL Server 不会让您使用加密数据库,因此如果您无法解密您拥有的数据库,则必须将该数据放入已解密的数据库中。
    • 我明白了。我想,我已经找到了解决方案:我将使用 Access 打开我的 mdb 数据库并将所有对象导出到一个新的 accdb 文件,然后我将使用 SQL 迁移工具。
    猜你喜欢
    • 2010-09-22
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 2011-03-15
    • 2012-11-28
    • 1970-01-01
    相关资源
    最近更新 更多