首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我可以比较两个ms-access文件吗?

问我可以比较两个ms-access文件吗?
EN

Stack Overflow用户
提问于 2008-10-27 09:49:27
回答 7查看 28.8K关注 0票数 9

我想要比较两个ms-access .mdb文件,以检查它们包含的数据在两者中是否相同。

我该怎么做呢?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2008-10-27 21:17:32

我在代码中做过很多次这样的事情,主要是在本地MDB需要从网站上输入的数据中提取更新的情况下。在一种情况下,网站是由MDB驱动的,在另一种情况下,它是MySQL数据库。对于MDB,我们刚刚下载了它,对于MySQL,我们在网站上运行脚本来导出和FTP文本文件。

现在,重点是我们希望将本地MDB中的数据与从网站下载的数据进行比较,并更新本地MDB以反映网站上所做的更改(不,不可能使用单个数据源--这是我建议的第一件事,但它不可行)。

让我们称MDB A为本地数据库,MDB B为您正在下载以进行比较的数据库。你需要检查的是:

存在于MDB A中但不存在于MDB B中的

  1. 记录。这些可能是删除的候选记录,也可能不是要删除的记录(这将取决于您的特定数据)。存在于MDB但不存在于MDB A中的
  2. 记录。您将从MDB附加到MDB A。同时存在于两者中的
  3. 记录,需要逐个字段进行比较。

通过使用外部连接来查找丢失的记录的查询,可以相当容易地完成步骤#1和#2。步骤3需要一些代码。

代码背后的原则是两个MDB中的所有表的结构都是相同的。因此,您可以使用DAO遍历TableDefs集合,打开一个记录集,并遍历fields集合,以便对每个表的每一列运行一个SQL语句,以更新数据或输出差异列表。

代码背后的基本结构是:

代码语言:javascript
复制
  Set rs = db.OpenRecordset("[SQL statement with the fields you want compared]")
  For Each fld In rs.Fields
    ' Write a SQL string to update all the records in this column
    '   where the data doesn't match
    strSQL = "[constructed SQL here]"
    db.Execute strSQL, dbFailOnError
  Next fld

现在,这里的主要复杂性是每个字段的WHERE子句必须不同--文本字段需要与数字和数据字段不同地处理。因此,您可能需要一个SELECT CASE来根据字段类型编写WHERE子句:

代码语言:javascript
复制
  Select Case fld.Type
    Case dbText, dbMemo
    Case Else
  End Select

您将希望使用Nz()来比较文本字段,但是您将使用Nz(TextField,'')来比较文本字段,而使用Nz(NumericField,0)来比较数值字段或日期字段。

我的示例代码实际上并没有使用上面的结构来定义WHERE子句,因为它仅限于与ZLS (文本字段)连接在一起工作得非常好的字段。下面的内容读起来相当复杂,但它基本上是对上面结构的扩展。

它是为了提高更新效率而编写的,因为它为表的每个字段执行一次SQL更新,这比为每一行执行一次SQL更新效率要高得多。另一方面,如果您不想进行更新,但又想要一个差异列表,那么您可能会以不同的方式对待整个问题。但根据输出结果,这会变得相当复杂,

如果您只想知道两个MDB是否相同,则首先检查每个表中的记录数,如果有一个不匹配,则退出并告诉用户MDB不同。如果记录计数相同,那么您必须逐个字段地检查,我认为这最好使用动态编写的逐列SQL来完成--一旦一个结果SQL SELECTS返回1条或更多记录,您就中止并告诉您的用户MDB不相同。

复杂的部分是,如果你想记录差异并通知用户,但这将使这篇已经没完没了的帖子变得更长!

下面是一个更大的子例程的一部分代码,该子例程使用来自qdfNewMembers (来自MDB )的数据更新保存的查询qdfOldMembers (来自MDB )。第一个参数strSQL是一个SELECT语句,它仅限于要比较的字段,而strTmpDB是另一个MDB (在我们的示例中是MDB B)的路径/文件名。代码假设strTmpDB已经创建了qdfNewMembers和qdfOldMembers (原始代码动态编写保存的QueryDef )。它也可以是直接的表名称(我使用保存的查询的唯一原因是因为字段名在为其编写的两个MDB之间不完全匹配)。

代码语言:javascript
复制
Public Sub ImportMembers(strSQL As String, strTmpDB As String)
  Const STR_QUOTE = """"
  Dim db As Database
  Dim rsSource As Recordset '
  Dim fld As Field
  Dim strUpdateField As String
  Dim strZLS As String
  Dim strSet As String
  Dim strWhere As String

  ' EXTENSIVE CODE LEFT OUT HERE

  Set db = Application.DBEngine(0).OpenDatabase(strTmpDB)

  ' UPDATE EXISTING RECORDS
  Set rsSource = db.OpenRecordset(strSQL)
  strSQL = "UPDATE qdfNewMembers INNER JOIN qdfOldMembers ON "
  strSQL = strSQL & "qdfNewMembers.EntityID = qdfOldMembers.EntityID IN '" _
                       & strTmpDB & "'"
  If rsSource.RecordCount <> 0 Then
     For Each fld In rsSource.Fields
       strUpdateField = fld.Name
       'Debug.Print strUpdateField
       If InStr(strUpdateField, "ID") = 0 Then
          If fld.Type = dbText Then
             strZLS = " & ''"
          Else
             strZLS = vbNullString
          End If
          strSet = " SET qdfOldMembers." & strUpdateField _
                     & " = varZLStoNull(qdfNewMembers." & strUpdateField & ")"
          strWhere = " WHERE " & "qdfOldMembers." & strUpdateField & strZLS _
                       & "<>" & "qdfNewMembers." & strUpdateField & strZLS _
                       & " OR (IsNull(qdfOldMembers." & strUpdateField _
                       & ")<>IsNull(varZLStoNull(qdfNewMembers." _
                       & strUpdateField & ")));"
          db.Execute strSQL & strSet & strWhere, dbFailOnError
          'Debug.Print strSQL & strSet & strWhere
       End If
     Next fld
  End If
End Sub

函数varZLSToNull()的代码:

代码语言:javascript
复制
Public Function varZLStoNull(varInput As Variant) As Variant
  If Len(varInput) = 0 Then
     varZLStoNull = Null
  Else
     varZLStoNull = varInput
  End If
End Function

我不知道这是不是太复杂了,没有意义,但也许它会对某些人有所帮助。

票数 6
EN

Stack Overflow用户

发布于 2011-09-06 03:15:42

您可以尝试AccessDiff (付费产品)。它具有比较模式、数据和访问对象的能力。它有一个GUI和一个命令行界面。

披露:我是这个工具的创建者。

票数 5
EN

Stack Overflow用户

发布于 2008-10-27 10:37:36

获取数据库表的文本转储,并使用BeyondCompare (或任何其他文本比较工具)简单地比较转储的文本文件。粗糙,但可以工作!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/239450

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档