为什么 DLookup 不 return 交易期间更新的值?
Why does DLookup not return the values updated during a transaction?
我在我的 MS Access VBA 代码中使用事务。我更新了我的字段之一,我的清单 table 中的 Incoming_Pieces
字段。然后,在提交事务之前,我在更新的字段上使用 DLookup
。 DLookup
函数将 return 事务前的值,而不是提交前事务期间更新的值。
这是故意的吗?没有错误消息或任何警告表明我正在检索的数据与事务中正在更新的数据不同步。
是生成 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。
在查询中,我们可以区分2个范围:
- 申请。这些查询可以使用用户定义的函数,并且可以引用基于表单的参数(例如
WHERE MyField = Forms!SomeForm!SomeControl
)。
- 数据库引擎(DAO/ODBC/Others):这些查询不能引用应用程序中发生的任何事情,因此不能使用 VBA 中定义的函数,也不能使用基于表单的参数,但会受到影响如果他们操作的 connection/workspace 开始一个交易,则按交易。
如果我们想查询一个事务内部发生了什么,我们需要在同一个范围内。这意味着您需要重写 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
我在我的 MS Access VBA 代码中使用事务。我更新了我的字段之一,我的清单 table 中的 Incoming_Pieces
字段。然后,在提交事务之前,我在更新的字段上使用 DLookup
。 DLookup
函数将 return 事务前的值,而不是提交前事务期间更新的值。
这是故意的吗?没有错误消息或任何警告表明我正在检索的数据与事务中正在更新的数据不同步。
是生成 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。
在查询中,我们可以区分2个范围:
- 申请。这些查询可以使用用户定义的函数,并且可以引用基于表单的参数(例如
WHERE MyField = Forms!SomeForm!SomeControl
)。 - 数据库引擎(DAO/ODBC/Others):这些查询不能引用应用程序中发生的任何事情,因此不能使用 VBA 中定义的函数,也不能使用基于表单的参数,但会受到影响如果他们操作的 connection/workspace 开始一个交易,则按交易。
如果我们想查询一个事务内部发生了什么,我们需要在同一个范围内。这意味着您需要重写 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