获取最后插入记录的ID-访问DAO,ODBC,SQL Server 2008标识字段

HK1*_*HK1 3 ms-access odbc vba sql-server-2008

这是一个非常常见的问题,但是我在获取最后插入的记录的ID时遇到了麻烦。我正在使用DAO和ODBC链接表来复制一条记录及其子记录。我的表在SQL Server 2008中,并且具有ID字段的Identity字段。

到目前为止,这是我尝试过的。我的第一部分代码将导致错误3167,“记录已删除”。如果我执行debug.Print记录集实际上包含3条记录。

Dim r as DAO.Recordset, db as DAO.Database
Set db = CurrentDb
Set r = db.OpenRecordset("SELECT TOP 2 * FROM item ORDER BY DateTimeModified DESC", dbOpenDynaset, dbSeeChanges)
r.AddNew
'Set field values here
r.Update 'Completes without error
r.Bookmark = r.LastModified
Debug.Print r("ItemID") 'Error 3167, Record is deleted
Run Code Online (Sandbox Code Playgroud)

这是我尝试的下一件事:

Debug.Print db.OpenRecordset("SELECT @@identity FROM item")(0)
Run Code Online (Sandbox Code Playgroud)

最后一个完成没有任何问题,但返回的值不正确。在实际的新ItemID为321的情况下,它将返回值614。它所返回的值确实是递增的(随着我不断测试该值而改变),但它似乎根本与我的表无关。没有值为614的字段。我已仔细检查以确保我在查找正确的表。

我知道我可以使用DLookup或DMax之类的东西,但我认为在多用户环境中,这不会被视为防弹产品。

我想我可以在ADO中使用存储过程来解决这个问题。我想知道这是否是我唯一的选择?

Edit1:
我现在正在使用以下代码,它正在做我需要/想要的事情。我怀疑这与使用DMax基本相同。

Dim r as DAO.Recordset, db as DAO.Database
Set db = CurrentDb
Set r = db.OpenRecordset("SELECT TOP 1 * FROM item ORDER BY ItemID DESC", dbOpenDynaset, dbSeeChanges)
r.AddNew
'Set field values here
r.Update
r.Requery
r.MoveFirst
Debug.Print r("ItemID")
Run Code Online (Sandbox Code Playgroud)

ta.*_*.is 5

据我所知,@@IDENTITY它不适用于基于游标的插入。DAO和ADO都在后台使用光标。

.Update记录之后,您应该只需读取值即可获取身份值。

通过使用Keyset语义打开的ADO Recordset,以下对我来说很好用:

r.Update
Debug.Print r("ItemID")
Run Code Online (Sandbox Code Playgroud)

通过使用Dynaset语义打开的DAO记录集,以下对我来说很好用:

r.Update
r.Bookmark = r.LastModified
Debug.Print r("ItemID")
Run Code Online (Sandbox Code Playgroud)

您应该避免使用.Requery.MoveFirst,这会引入并发问题。考虑:

Dim r as DAO.Recordset, db as DAO.Database
Set db = CurrentDb
Set r = db.OpenRecordset("SELECT TOP 1 * FROM item ORDER BY ItemID DESC", dbOpenDynaset, dbSeeChanges)
r.AddNew
''// Set field values here
r.Update
''// At this point another user adds a new record
r.Requery
r.MoveFirst ''// ORDER BY ItemID DESC means that you're going to see the new user's row
Debug.Print r("ItemID")
Run Code Online (Sandbox Code Playgroud)