由于我无法控制的原因,我们使用Access 2010更新链接的SharePoint列表,以使它们与我们的CMDB保持同步。我们以CSV格式从CMDB获取报告,并将它们链接到Access。然后,我们使用Access VBA和预定义查询的组合来添加新数据,或者更新或软删除现有数据。特别是一个列表导致问题。具体来说,插入/软删除似乎工作,但Access在运行更新查询时耗尽资源和崩溃。拉起资源监视器显示内存使用量随着应用程序的运行而不断增加,并且当〜1.6 GB或RAM分配给它时,Access最终会失败(在具有6 GB交换文件的4 GB计算机上,Windows 7 64位,但是32位访问)。
除VBA代码外,我还使用了两个查询。一个查询检索结果集,该结果集允许我确定要更新SharePoint列表中的哪一行(如果有),而另一个查询则标识报表中的哪些列更新SharePoint列表中的相应列,链接报表之间的连接条件和相应的列表,以及要更新的SP中的行,由其组合键标识。我认为这是相当标准的东西。
由于SharePoint列表具有关联的工作流,因此我们必须使用此方法(或一种基本相似的方法)。我们发现,如果我们编写SQL来执行标准的集合类型更新,则更新发生得太快,会导致Sharepoint的工作流引擎过载并导致工作流失败。
我尝试过多种替代技术:
这是执行查询的VBA代码:
Private Sub runUpdt()
Dim oQdfUpdt As DAO.QueryDef
Dim oRs As DAO.Recordset
Dim oWrkSpc As DAO.Workspace
Dim strmsg As String
On Error GoTo Handler
logMsg "Entering method runUpdt in class clsAppFsFin"
Debug.Print "Entering method runUpdt in class clsAppFsFin", Now()
Set oRs = CurrentDb.QueryDefs("slctAppFsFinRowsForUpdt").OpenRecordset(dbOpenDynaset, dbReadOnly)
Set oQdfUpdt = CurrentDb.QueryDefs("updtAppFsFin")
Set oWrkSpc = DBEngine.Workspaces(0)
Do While (Not oRs.EOF)
oWrkSpc.BeginTrans
If (isUpdated(oRs)) Then
oQdfUpdt.Parameters("CHGTXT") = "System Change"
oQdfUpdt.Parameters("CID") = oRs.Fields("RYCID")
oQdfUpdt.Execute
' inserts a row into the flg_is_updt table
oFlgUpdt.insFlgIsUpdt oRs.Fields("RYAID")
ElseIf (oRs.Fields("SPCTX") <> "System NoChange") Then
oQdfUpdt.Parameters("CHGTXT") = "System NoChange"
oQdfUpdt.Parameters("CID") = oRs.Fields("RYCID")
oQdfUpdt.Execute
' inserts a row into the flg_is_updt table
oFlgUpdt.insFlgIsUpdt oRs.Fields("RYAID")
End If
oWrkSpc.CommitTrans
If ((oRs.AbsolutePosition Mod 100 = 0) And (oRs.AbsolutePosition > 0)) Then
strmsg = "Updated " & oRs.AbsolutePosition & " rows. Class: clsAppFsFin, Method: runUpdt."
Debug.Print strmsg, Now()
logMsg strmsg
Dim curFSCID As String
curFSCID = oRs.Fields("RYCID")
oRs.Close
Set oRs = Nothing
oQdfUpdt.Close
Set oQdfUpdt = Nothing
Set oRs = CurrentDb.QueryDefs("slctAppFsFinRowsForUpdt").OpenRecordset
Set oQdfUpdt = CurrentDb.QueryDefs("updtAppFsFin")
oRs.FindFirst "RYCID = '" & curFSCID & "'"
End If
' sleep .1 seconds to avoid overloading the upstream workflow
Sleep SLEEPTIMEINMILLIS
oRs.MoveNext
Loop
strmsg = "Final update count: " & oRs.RecordCount & " rows. Class: clsAppFsFin, Method: runUpdt."
logMsg strmsg
Debug.Print strmsg, Now()
oRs.Close
oQdfUpdt.Close
Set oRs = Nothing
Set oQdfUpdt = Nothing
Debug.Print "Exiting method runUpdt in class clsAppFsFin", Now()
logMsg "Exiting method runUpdt in class clsAppFsFin"
Exit Sub
Handler:
oWrkSpc.Rollback
Debug.Print Err.Number, Err.Description
logError Err.Number, Err.Description
End Sub
以下是VBA代码执行的选择和更新查询
选择查询:
SELECT APFF.[App ID] AS SPAID,
APFF.Server AS SPHST,
APFF.Directory AS SPDIR,
RAppAH.AppID AS RYAID,
RAppAH.Host AS RYHST,
RAppAH.FSCID AS RYCID
<
snip
>
FROM (AppCert
INNER JOIN AppFileSystemFin AS APFF
ON AppCert.[App ID] = APFF.[App ID])
LEFT JOIN RAppAH
ON APFF.FSCID = RAppAH.FSCID
WHERE APFF.FSCID = [RAppAH].[FSCID]
AND AppCert.State = "8 - Complete"
AND RAppAH.FSCID IS NOT NULL
AND APFF.[Change In SoR - Text] <> "System Remove"
ORDER BY APFF.ID;
更新查询:
UPDATE AppFileSystemFin
INNER JOIN RAppAH
ON AppFileSystemFin.FSCID = RAppAH.FSCID
SET AppFileSystemFin.Server = [RAppAH].[Host],
AppFileSystemFin.Directory = [RAppAH].[Directory],
<
snip
>
WHERE AppFileSystemFin.ID = [ID];
答案 0 :(得分:0)
问题现已解决。在上面显示的更新查询中,行:
在哪里AppFileSystemFin.ID = [ID];
未引用Sharepoint的系统生成的ID列。相反,它指的是我们必须使用的内部生成的键字段,以便能够在列表之间执行SQL连接操作。
查询已更新为使用SharePoint生成的ID列。这个次要更新解决了内存分配问题,反过来又允许更新更快地进行 - 现在只需要前一个运行时的大约三分之一来完成执行。