在 MS Access 中运行异步查询
Posted
技术标签:
【中文标题】在 MS Access 中运行异步查询【英文标题】:Running asynchronous query in MS Access 【发布时间】:2011-01-27 08:51:28 【问题描述】:我正在尝试异步运行一些繁重的查询,但不知道如何为 .mdb 文件执行此操作。
这是我目前所拥有的:
Dim wrksp As Workspace, qdf As QueryDef, rst As Recordset
Dim cnn As Connection, strConnect As String
Set wrksp = CreateWorkspace("ODBCDirect", "Admin", "", dbUseODBC)
strConnect = "ODBC;Driver=Microsoft Access Driver (*.mdb);Database=F:\Databank\webshop_ingrid.mde;Uid=;Pwd=;"
Set cnn = wrksp.OpenConnection("", dbDriverNoPrompt, False, _
strConnect)
Dim rs As Recordset
Dim strQuery As String
strQuery = "UPDATE ((((((tblSkuActueel LEFT JOIN qryStockSkuMetLaatsteDatumSubQuery ON tblSkuActueel.sku = qryStockSkuMetLaatsteDatumSubQuery.sku) LEFT JOIN " & _
"qrySkuCapNieuwste ON tblSkuActueel.sku = qrySkuCapNieuwste.sku) LEFT JOIN qrySkuListNieuwste ON tblSkuActueel.sku = qrySkuListNieuwste.sku) LEFT JOIN " & _
"qrySkuPPDNieuwste ON tblSkuActueel.sku = qrySkuPPDNieuwste.sku) INNER JOIN qrySkuApexNieuwsteMetBtw ON tblSkuActueel.sku = qrySkuApexNieuwsteMetBtw.sku) " & _
"LEFT JOIN qrySkuSpecialNieuwsteDS ON tblSkuActueel.sku = qrySkuSpecialNieuwsteDS.sku) LEFT JOIN qrySkuSpecialNieuwsteNB ON tblSkuActueel.sku = " & _
"qrySkuSpecialNieuwsteNB.sku SET tblSkuActueel.stock = qryStockSkuMetLaatsteDatumSubQuery.aantal, tblSkuActueel.apex = qrySkuApexNieuwsteMetBtw.apex, " & _
"tblSkuActueel.cap = qrySkuCapNieuwste.cap, tblSkuActueel.listprice = qrySkuListNieuwste.listprice, tblSkuActueel.ppd = qrySkuPPDNieuwste.ppd, " & _
"tblSkuActueel.procent = qrySkuApexNieuwsteMetBtw.procent, tblSkuActueel.apin = Round(qrySkuApexNieuwsteMetBtw.apex*qrySkuApexNieuwsteMetBtw.procent,2), " & _
"tblSkuActueel.BtwId = qrySkuApexNieuwsteMetBtw.btwid, tblSkuActueel.specialpricenb = [qryskuspecialnieuwstenb].[specialprice], " & _
"tblSkuActueel.specialpriceds = [qryskuspecialnieuwsteds].[specialprice]"
Set rs = Object.OpenRecordset(strQuery, dbOpenDynaset, dbSeeChanges + dbRunAsync)
这甚至不会打开连接,因为连接字符串似乎是错误的。
【问题讨论】:
related question 中的讨论可能会有所帮助 【参考方案1】:您的前 5 行(非空白)在您的示例中没有执行任何操作。这些行试图打开一个连接,但您稍后处理更新查询的代码没有使用该连接。
您应该知道,您正在使用的 Round() 函数可能不会返回您期望的结果。 VBA 中的 Round() 函数使用“Bankers Rounding”或“round half to even”逻辑。 Round(15.665,2) 和 Round(15.675,2) 都将返回 15.67。
您的最后一行试图从您的更新语句中打开一个记录集。更新语句不返回记录,因此没有要返回的记录集。如果它要返回一个记录集,你会想要使用类似“CurrentDB.OpenRecordset”而不是“Object.OpenRecordset”的东西。
关于这个查询的异步运行,你可能得不到你想要的。 MS Access 将在本地计算机上处理查询。如果使用 JET (MS Access) 数据库,我不知道异步运行查询的方法。我怀疑即使有一个命令通过您的 VBA 代码异步运行查询,它仍然会在您的应用程序的上下文中运行并陷入困境。
如果您试图让您的应用程序在查询运行时做出响应,我建议您将更新移至单独的进程,例如 VBScript 文件。
将以下代码保存在一个名称类似于 UpdateActueel.vbs 的文件中
strQuery = "UPDATE ((((((tblSkuActueel LEFT JOIN qryStockSkuMetLaatsteDatumSubQuery ON tblSkuActueel.sku = qryStockSkuMetLaatsteDatumSubQuery.sku) LEFT JOIN " & _
"qrySkuCapNieuwste ON tblSkuActueel.sku = qrySkuCapNieuwste.sku) LEFT JOIN qrySkuListNieuwste ON tblSkuActueel.sku = qrySkuListNieuwste.sku) LEFT JOIN " & _
"qrySkuPPDNieuwste ON tblSkuActueel.sku = qrySkuPPDNieuwste.sku) INNER JOIN qrySkuApexNieuwsteMetBtw ON tblSkuActueel.sku = qrySkuApexNieuwsteMetBtw.sku) " & _
"LEFT JOIN qrySkuSpecialNieuwsteDS ON tblSkuActueel.sku = qrySkuSpecialNieuwsteDS.sku) LEFT JOIN qrySkuSpecialNieuwsteNB ON tblSkuActueel.sku = " & _
"qrySkuSpecialNieuwsteNB.sku SET tblSkuActueel.stock = qryStockSkuMetLaatsteDatumSubQuery.aantal, tblSkuActueel.apex = qrySkuApexNieuwsteMetBtw.apex, " & _
"tblSkuActueel.cap = qrySkuCapNieuwste.cap, tblSkuActueel.listprice = qrySkuListNieuwste.listprice, tblSkuActueel.ppd = qrySkuPPDNieuwste.ppd, " & _
"tblSkuActueel.procent = qrySkuApexNieuwsteMetBtw.procent, tblSkuActueel.apin = Round(qrySkuApexNieuwsteMetBtw.apex*qrySkuApexNieuwsteMetBtw.procent,2), " & _
"tblSkuActueel.BtwId = qrySkuApexNieuwsteMetBtw.btwid, tblSkuActueel.specialpricenb = [qryskuspecialnieuwstenb].[specialprice], " & _
"tblSkuActueel.specialpriceds = [qryskuspecialnieuwsteds].[specialprice]"
Set DB = GetObject("F:\Databank\webshop_ingrid.mde")
DB.Execute strQuery
在您的 VBA 代码中,使用以下行来运行脚本。
Shell "wscript ""C:\<Path to file>\UpdateActueel.vbs"""
【讨论】:
我认为 ADO 记录集可以是 DML 查询。【参考方案2】:我可以谈论针对 JET 数据源执行此操作,但是我已针对 SQL Server 使用此操作,因此它应该可以工作。诀窍是使用 ADO 并使用选项 adAsyncExecute 触发执行语句。我手头没有确切的代码,但这是我脑海中的一个粗略版本
将 DbCon 调暗为 ADODB.Connection
将 dbCmd 调暗为 ADODB.Command
DbCon.ConnectionString=”你的 连接字符串”
使用 dbCmd .commandtype=adCmdText
.commandtext=”您的长 SQL 更新语句” .ActiveConnection=dbcon
.Execute , , adAsyncExecute
结束
【讨论】:
嗯,我不认为它适用于 MDB 数据库,因为它抱怨 OLE DB 对象'当前提供者不支持' 值得一试,你能告诉我错误出现在代码的哪一行吗?以上是关于在 MS Access 中运行异步查询的主要内容,如果未能解决你的问题,请参考以下文章
从 MS Access VBA 通过 ODBC 进行 MySQL 查询:ADODB 异步执行不起作用
使用 SQL 在 Ms-access 查询中运行 Total
查询在 MS-Access 中运行良好,但不能通过 jet 4 在 .net 中执行