Microsoft Access 2010 内存泄漏 DAO 记录集和 RUNSQL

问题描述 投票:0回答:2

我的问题是,随着更新循环的每次迭代,我都会丢失大约 100k 的内存,因此最终,在几千次迭代后我会收到资源不足错误。

问题是,为什么我会失去记忆?

下面是一个循环更新数据的代码片段。

标准是从本地数据库中提取的,dao.recordset方法。 -- rs1

比较来自将要进行更新的目标数据库,dao.recordset方法。 -- rs2 是读取的目标,看看我是否需要进行更新

更新是对链接的共享点表进行 Docmd.Runsql 查询。 是的,我知道我可以使用 .edit 和 .update,但在这种情况下,不同的帖子会发生其他奇怪的事情。 :)

将 2010 访问到 Sharepoint 2010 中

Dim db As DAO.Database
Dim rs1 As DAO.Recordset
Dim rs2 As DAO.Recordset

Set db = CurrentDb
Set rs1 = db.OpenRecordset("datefix")

Do While Not rs1.EOF
    Set rs2 = db.OpenRecordset("select `Required delivery` from xyzzy where `SO Line` = '" & rs1.Fields(0).Value & "'")
    If rs1.Fields(1).Value = rs2.Fields("Required delivery") Then
    Else
        DoCmd.RunSQL "update ProblemTracking set `Required delivery` = '" & rs1.Fields(1).Value & "', `1st GI Dat` = '" & rs1.Fields(2).Value & "' where `SO Line` = '" & rs1.Fields(0).Value & "'"
    End If
    rs2.Close
    Set rs2 = Nothing

    rs1.MoveNext
Loop
ms-access memory vba
2个回答
0
投票

考虑将 VBA 记录集转换为一个存储的操作查询。您会在 SQL 中看到,

JOIN
被视为显式联接,而
WHERE
被视为隐式联接。优化器等效地运行这两个。更新查询可以使用 join 语句。此外,与 VBA 查询相比,存储查询由数据库进行分析、优化和缓存,并在内部存储最佳执行计划。

如果我正确地阅读了您的代码,您将拥有三个表:

datefix
xyzzy
ProblemTracking
,全部由
SO Line
连接(并且无论
dateFix
中的相应列作为您的示例使用字段编号而不是名称) )。基本上,只要
[Required delivery]
对应的第二列不等于
[1st GI Dat]
中的
ProblemTracking
,您就需要更新
dateFix
中的
[Required delivery]
xyzzy
字段。

因此,考虑将以下更新查询保存为其自己的对象,并使用 DoCmd.OpenQuery 在 VBA 中运行它:

UPDATE (ProblemTracking 
INNER JOIN datefix ON ProblemTracking.`SO Line` = datefix.`FirstColumn`)
INNER JOIN xyzzy ON xyzzy.`SO Line` = datefix.`FirstColumn`
  SET `Required delivery` = datefix.`SecondColumn`, `1st GI Dat` = datefix.`ThirdColumn` 
WHERE datefix.SecondColumn <> xyzzy.`Required delivery` 

现在,如果上面不是一个 updatedatable 查询,请使用 DLookUp():

UPDATE ProblemTracking 
INNER JOIN datefix
ON ProblemTracking.`SO Line` = datefix.`FirstColumn`
WHERE datefix.SecondColumn <> 
      DLookUp("[Required delivery]", "xyzzy", "[SO Line]='" & datefix.FirstColumn & "'")

但是,如果您坚持使用 VBA 记录集,仍应考虑在仅使用一个记录集的

SELECT
查询中连接所有三个表。

Dim db As DAO.Database
Dim rs As DAO.Recordset

Set db = CurrentDb

' PULLING ONLY NEEDED COLUMNS IN JOIN OF THREE TABLES
strSQL = "SELECT datefix.`FirstColumn`, datefix.`SecondColumn`, datefix.`ThirdColumn`" _ 
          & " FROM (ProblemTracking" _ 
          & " INNER JOIN datefix ON ProblemTracking.`SO Line` =  datefix.`FirstColumn`)" _
          & " INNER JOIN xyzzy ON xyzzy.`SO Line` = datefix.`FirstColumn`" _
          & " WHERE datefix.SecondColumn <> xyzzy.`Required delivery`;" 

Set rs = db.OpenRecordset(strSQL)

rs.MoveLast
rs.MoveFirst

Do While Not rs.EOF
    DoCmd.RunSQL "UPDATE ProblemTracking 
                  SET `Required delivery` = '" & rs.Fields(1).Value & "', 
                      `1st GI Dat` = '" & rs.Fields(2).Value & "' 
                  WHERE `SO Line` = '" & rs.Fields(0).Value & "'"
    rs.MoveNext
Loop

rs.Close
Set rs = Nothing

0
投票

我开始在 Windows 10 中出现记录集内存泄漏。我意识到使用 Fields 属性

rs1.Fields(0).Value
读取记录集值是导致内存泄漏的原因。如果我使用
rcd.GetRows(1)
方法读取该值,则不会出现内存泄漏。

请参阅此处有关 GetRows 的 Microsoft 文档:GetRows

© www.soinside.com 2019 - 2024. All rights reserved.