如何使用查询或 VBA 和 SQL 更新 MS ACCESS 中的表

Posted

技术标签:

【中文标题】如何使用查询或 VBA 和 SQL 更新 MS ACCESS 中的表【英文标题】:How to update tables in MS ACCESS with query or with VBA & SQL 【发布时间】:2021-06-19 17:23:17 【问题描述】:

我已经让我的数据库使用各种代码和解决方法,但效率不高!所以这是一个可以解决我很多问题的问题:

两个 ACCESS 表:Tab01 和 Tab02。两者都有相同的列标题,但列数不同。暂时不考虑主键和 ID,为了检查内容是否相同,我从每个表中选择了 3 列必须相同:日期、地点和时间。

现在如下:

Tab01.column01 包含第 1、4、5、8、10 行中的值

Tab01.column02 包含第 2、3、10 行中的值

Tab01.column03 包含第 1、2、3、4、5、6、7、8、9 行中的值


Tab02.column01 包含第 1、2、3、4、5、9、10 行中的值

Tab02.column02 不包含任何值

Tab02.column03 包含第 1、10 行中的值

如果我想用 Tab02.columnX 中的值完成 Tab01.columnX 中的缺失值(通过使用设置为 ID 的 3 个值 Date、Time、Place):

如何在这里进行?使用表格查询?第三张桌子?使用 VBA 和 SQL 代码?我选择了使用大量 VBA 代码和 If-Then 语句的方式。完成表格的值大约需要 30 分钟 (!!!!)。准确的说是十几张表,每张表大约有1000行10列左右,其中的值看起来像这样,需要补全。

但不管怎样,继续使用上面描述的两个表,我正在寻找一种可能更优雅、更快速的方式来更新 Tab01。有没有人有好的建议?非常感谢!

这就是我的 Tab01 和 Tab02 代码的样子:(我在所有其他表中使用 ca. 20 -30 !!!!)

Sub CompTabsExmpl()

Dim x As Long, y As Long
Dim xRecsMain As Long, xRecsSub As Long

Dim db As DAO.Database
Dim rsTab01 As DAO.Recordset
Dim rsTab02 As DAO.Recordset

Set db = CurrentDb
Set rsTab01 = db.OpenRecordset("Table01", dbOpenDynaset)
Set rsTab02 = db.OpenRecordset("Table02", dbOpenDynaset)

xRecsMain = DCount("*", "Table01")
xRecsSub = DCount("*", "Table02")

rsTab01.MoveFirst
rsTab02.MoveFirst

For y = 0 To xRecsMain - 1
    
   For x = 0 To xRecsSub - 1
   
      If rsTab01.Fields("fieldDATE") = rsTab02.Fields("fieldDATE") And _
         rsTab01.Fields("fieldTIME") = rsTab02.Fields("fieldTIME") And _
         rsTab01.Fields("fieldPLACE") = rsTab02.Fields("fieldPLACE") And _
         IsNull(rsTab01.Fields(fieldX)) And _
         Not IsNull(rsTab02.Fields(fieldX)) Then

         rsTab01.Edit
         rsTab01.Fields("fieldX") = rsTab02.Fields("fieldX")
         'same for all other fields ....
         'same for all other fields ....
         'same for all other fields ....
         '...
         rsTab01.Update
       End If
      
         rsTab01.MoveNext
   Next
    
         rsTab01.MoveFirst
         rsTab02.MoveNext
    
Next

rsTab01.Close
rsTab02.Close
db.Close

End Sub

【问题讨论】:

好吧,你想要一个所有结果的联合 - 但没有重复。或者您是否需要有代码来检查/防止/查找匹配项?我的意思是您可以构建所有 3 个表的联合查询 - 使用选择不同的行发送结果 - 这将运行得非常快。所以这里的真正目标是个问题。显示没有重复的行,或者查找+搜索以防止重复?当然,通过良好的数据库规范化,我们希望避免在系统中出现这样的重复数据。首先。有一些方法可以绕过 sql 引擎进行 BLISTERING 快速匹配。 在我的例子中只有两个表,我想要更新 Tab01(通过 Tab01 中的缺失值,这些值散布在 Tab02 中)。 【参考方案1】:

好的,到目前为止,我们遇到了这个问题:

获取table2中缺失的值并移动到table1中

(但匹配 3 列)。好的,我会为此使用查询生成器 - 它会运行得非常快。

所以,创建一个新查询。放入两个表(确保主表(第一个表)首先放入。

现在,进入第二张桌子。向查询网格添加左侧表(我们要更新的主表)中的 PK id。

所以,我打算用 tblHotels 和 tblHotelsB 来做这个

我想匹配 FirstName、HotelName、City 和 TRANSFER 两列 HotelTax 和 Description。

那么,查询生成器?从左侧表格中拖出一条连接线(始终以正确的方向拖放连接线非常重要)。

您现在可以运行查询 - 它运行了吗??? (而且它应该运行得非常快 - 特别是如果您在每个表的 3 列上都有索引。

好的,让这个查询正常工作!!!!!!!

看起来像这样:

如前所述,双击 PK id(将其放入网格中)。对要复制的所有列执行相同操作。

现在,右键单击查询生成器中的任何空白区域,然后更改更新查询的查询类型 - 如下所示:

现在,只需在更新的表达式中,输入 tableB 中的字段

你明白了:

注意非常小心 - 更新到(表达式可以是我们想要的任何内容 - 这也允许您输入第二个表中的列。

当然,做这样危险操作的备份。

【讨论】:

感谢 Kallal 先生的努力。我会试试这个,看看它是否适用于我的情况。并且:如果手术太危险,我会叫我的身体 Ethan Hunt,他会处理它;-) // 一个问题:在上述情况下使用主键是否绝对有必要获得正确的值,或者如果两个表中的三个选定字段匹配并充当ID就足够了?不幸的是,我的表没有主键(由于灵活性的原因,故事很复杂,我知道这不是最佳的,但现在我无法更改所有表的结构等)。 好的,您当然可以将 PK 排除在查询之外(当我构建查询时 - 我不假思索地包含了 PK - 有点像当您想打开灯时,请确保它插入。所以,现在可能 20 年了,因为我没有遗漏 PK。但是,是的,上面的查询肯定会在没有 pk 的情况下工作。但如果这些是访问表(没有链接到 sql server),那么是的 -以上将起作用。(使用 GUI 构建该查询需要 20 秒 - 根本不需要代码。但是是的,这将并且应该起作用 - 即使两个表都没有 PK。唯一的要求是连接字段是相同的输入 非常感谢!

以上是关于如何使用查询或 VBA 和 SQL 更新 MS ACCESS 中的表的主要内容,如果未能解决你的问题,请参考以下文章

使用 VBA 或 PowerShell 将所有 MS Access SQL 查询导出到文本文件

如何使用 VBA 动态 SQL SELECT 语句调用 MS Access 参数查询

如何使用 MySQl 的 ODBC 连接器在 MS Access 中的 VBA 中执行和查询?

在 MS Access 中回滚多个 SQL 更新查询

使用 VBA (MS Access) 中的 bigint 字段更新 SQL 表

使用 Excel VBA 查询 MS Access,SQL BETWEEN 日期查询