我的问题是,随着更新循环的每次迭代,我都会丢失大约 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
考虑将 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
我开始在 Windows 10 中出现记录集内存泄漏。我意识到使用 Fields 属性
rs1.Fields(0).Value
读取记录集值是导致内存泄漏的原因。如果我使用 rcd.GetRows(1)
方法读取该值,则不会出现内存泄漏。
请参阅此处有关 GetRows 的 Microsoft 文档:GetRows