为什么DLookup不返回交易期间更新的值



我在MS Access VBA代码中使用事务。我更新了其中一个字段,即Inventory表中的Incoming_Pieces字段。然后,在提交事务之前,我在更新的字段上使用DLookupDLookup函数将返回事务前的值,而不是提交前事务期间更新的值。

这是有意的吗?没有任何错误消息或任何警告表明我正在检索的数据与事务中正在更新的数据不同步。

生成SELECT语句而不是DLookup的唯一解决方法是什么?

这是我的测试代码来证明这一点。

Public Function testTransaction()
Dim pieces As Variant
pieces = DLookup("Incoming_Pieces", "Inventory", "Code='MT-1-1000x1x1'")
Debug.Print (pieces)    ' <------------ prints 0

DAO.DBEngine.BeginTrans

Dim sql As String
sql = "UPDATE Inventory SET Incoming_Pieces = 10 WHERE Code='MT-1-1000x1x1'"
CurrentDb.Execute (sql)
pieces = DLookup("Incoming_Pieces", "Inventory", "Code='MT-1-1000x1x1'")
Debug.Print (pieces)    ' <------------ prints 0
DAO.DBEngine.CommitTrans
pieces = DLookup("Incoming_Pieces", "Inventory", "Code='MT-1-1000x1x1'")
Debug.Print (pieces)    ' <------------ prints 10

End Function

DLookUp在应用程序范围内执行,而BeginTrans只影响数据库引擎范围,并且只影响DAO。

在查询中,我们可以区分两个范围:

  1. 应用程序。这些查询可以使用用户定义的函数,并且可以引用基于表单的参数(如WHERE MyField = Forms!SomeForm!SomeControl(
  2. 数据库引擎(DAO/ODBC/其他(:这些查询不能引用应用程序中发生的任何事情,因此不能使用VBA中定义的函数或基于表单的参数,但如果它们操作的连接/工作区启动了事务,则会受到事务的影响

如果我们想查询事务内部发生了什么,我们需要在同一范围内。这意味着您需要重写DLookUp才能使用记录集。

pieces = CurrentDb.OpenRecordset("SELECT Incoming_Pieces FROM Inventory WHERE Code='MT-1-1000x1x1'")(0).Value

一个更简单的例子来证明这一点:

DAO.DBEngine.BeginTrans
CurrentDb.Execute "INSERT INTO Table1(Field1) VALUES(1)"
Debug.Print CurrentDb.OpenRecordset("SELECT COUNT(*) FROM Table1")(0) 'Prints 1 assuming the table was empty
Debug.Print DCount("*", "Table1") 'Prints 0
DAO.DBEngine.Rollback

最新更新