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

时间:2015-08-18 14:51:07

标签: vba ms-access memory access-vba

我的问题是,随着更新循环的每次迭代,我丢失了大约100k的内存,所以最终,我在几千次迭代后得到了资源错误。

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

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

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

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

更新是对链接的sharepoint表的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

1 个答案:

答案 0 :(得分:0)

考虑将您的VBA记录集转换为一个存储的操作查询。您在SQL中看到,JOIN被视为显式连接,WHERE被视为隐式连接。优化器等效地运行这两个。更新查询可以使用join语句。此外,与VBA查询形成对比的存储查询由数据库进行分析,优化和缓存,并在内部存储最佳执行计划。

如果我正确阅读了您的代码,您有三个表:datefixxyzzyProblemTracking都由SO Line加入(以及{{{}}中的相应列1}},因为您的示例使用字段编号而不是名称)。基本上,只要dateFix中相应的第二列[Required delivery]不等于[1st GI Dat] ProblemTracking,就需要更新dateFix中的[Required delivery]xyzzy字段。

因此,请考虑将以下Update Query保存为自己的对象,并在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 query,请使用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