首页 > 解决方案 > 为什么 DLookup 不返回事务期间更新的值?

问题描述

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

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

是生成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

标签: vbams-accesstransactionsdlookup

解决方案


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

在查询中,我们可以区分 2 个作用域:

  1. 应用。这些查询可以使用用户定义的函数,并且可以引用基于表单的参数(例如WHERE MyField = Forms!SomeForm!SomeControl)。
  2. 数据库引擎(DAO/ODBC/Others):这些查询不能引用应用程序中发生的任何事情,因此不能使用 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

推荐阅读