最后插入行的自动编号值 - MS Access / VBA

Posted

技术标签:

【中文标题】最后插入行的自动编号值 - MS Access / VBA【英文标题】:Autonumber value of last inserted row - MS Access / VBA 【发布时间】:2009-10-27 01:18:27 【问题描述】:

我有一个JET 表,其中自动编号作为主键,我想知道在插入一行后如何检索该编号。我曾想过使用MAX() 来检索具有最高值的行,但不确定这有多可靠。一些示例代码:

Dim query As String
Dim newRow As Integer
query = "INSERT INTO InvoiceNumbers (date) VALUES (" & NOW() & ");"
newRow = CurrentDb.Execute(query)

现在我知道这行不通,因为Execute() 不会返回主键的值,但这基本上是我正在寻找的那种代码。我将需要使用新行的主键来更新另一个表中的一些行。

最简单/最易读的方法是什么?

【问题讨论】:

【参考方案1】:

在您的示例中,因为您使用 CurrentDB 来执行您的 INSERT,所以您自己变得更加困难。相反,这将起作用:

  Dim query As String
  Dim newRow As Long  ' note change of data type
  Dim db As DAO.Database

  query = "INSERT INTO InvoiceNumbers (date) VALUES (" & NOW() & ");"
  Set db = CurrentDB
  db.Execute(query)
  newRow = db.OpenRecordset("SELECT @@IDENTITY")(0)
  Set db = Nothing

我以前通过打开AddOnly 记录集并从那里获取ID 来执行插入操作,但这里的效率要高得多。请注意,它不需要ADO

【讨论】:

即使记录集是 SQL Server 链接表,它也可以工作!太棒了! 您还可以将 dbFailOnError 作为选项添加到执行。否则,如果访问失败,Access 将不会说任何话。 ----- db.Execute 查询,dbFailOnError @iDevlop SQL Server 支持the SELECT @@IDENTITY syntax。看看其他链接表类型(如 Excel)或其他 RDBMS(如 Oracle 或 mysql)会发生什么会很有趣。 这对我不起作用。我用 dao 插入了一个 SQL Server 表。我总是在 newRow 中得到 0。【参考方案2】:

如果DAO 使用

RS.Move 0, RS.LastModified
lngID = RS!AutoNumberFieldName

如果ADO 使用

cn.Execute "INSERT INTO TheTable.....", , adCmdText + adExecuteNoRecords
Set rs = cn.Execute("SELECT @@Identity", , adCmdText)
Debug.Print rs.Fields(0).Value

cn 是一个有效的 ADO 连接,@@Identity 将返回最后一个 Identity(自动编号)已插入此连接。

请注意,@@Identity 可能很麻烦,因为最后生成的值可能不是您感兴趣的值。对于 Access 数据库引擎,请考虑连接两个表的 VIEW,这两个表都有 IDENTITY财产,你INSERT INTOVIEW。对于 SQL Server,请考虑是否有触发器依次将记录插入到另一个同样具有 IDENTITY 属性的表中。

顺便说一句,DMax 不会像其他人在您插入一条记录之后但在您的 Dmax 函数完成执行之前插入一条记录一样工作,那么您将获得他们的记录。

【讨论】:

DAO 也可以执行 SELECT @@IDENTITY -- 你不需要 ADO。我一直这样做:lngID = db.OpenRecordset("SELECT @@IDENTITY")(0),其中“db”是用于执行插入的同一个数据库变量。我不再为此打开记录集和添加。 这对我不起作用。我用 dao 插入了一个 SQL Server 表。我收到一个错误:“记录已删除”(3167)【参考方案3】:

这是对我的代码的改编。我的灵感来自developpez.com(在页面中查找:“Pour insérer des données, vaut-il mieux passer par un RecordSet ou par une requête de type INSERT ?”)。他们解释(用一点法语)。这种方式比上一种要快得多。在示例中,这种方式快了 37 倍。试试看。

Const tableName As String = "InvoiceNumbers"
Const columnIdName As String = "??"
Const columnDateName As String = "date"

Dim rsTable As DAO.recordSet
Dim recordId as long

Set rsTable = CurrentDb.OpenRecordset(tableName)
Call rsTable .AddNew
recordId = CLng(rsTable (columnIdName)) ' Save your Id in a variable
rsTable (columnDateName) = Now()        ' Store your data
rsTable .Update

recordSet.Close

勒西格尼

【讨论】:

您能否确定它比哪个特定示例“快 37 倍”? 这对我不起作用。我用 dao 插入了一个 SQL Server 表。 recordId 始终相同 (1)。【参考方案4】:
Private Function addInsert(Media As String, pagesOut As Integer) As Long


    Set rst = db.OpenRecordset("tblenccomponent")
    With rst
        .AddNew
        !LeafletCode = LeafletCode
        !LeafletName = LeafletName
        !UNCPath = "somePath\" + LeafletCode + ".xml"
        !Media = Media
        !CustomerID = cboCustomerID.Column(0)
        !PagesIn = PagesIn
        !pagesOut = pagesOut
        addInsert = CLng(rst!enclosureID) 'ID is passed back to calling routine
        .Update
    End With
    rst.Close

End Function

【讨论】:

我看不出这是如何回答原始问题的。请添加上下文以查看这是否适合? 这个答案不清楚。请添加说明。并非所有人都知道关于 vba 的一切 注释行显示了收集 ID 的位置。您必须更改名称以匹配您的表 ID。格式:RecordName!IDName 虽然解释得不好,但这种格式对我有用,因为它最接近我已经使用的方法的结构。 这对我不起作用。我用 dao 插入了一个 SQL Server 表。 addInsert 总是一样的。【参考方案5】:

上面的两个例子都不适合我。在表上打开记录集并添加记录确实可以添加记录,除了:

myLong = CLng(rs!AutoNumberField)

如果放在 rs.AddNew 和 rs.Update 之间,则返回 Null。如果放在 rs.Update 之后,它确实会返回一些东西,但它总是错误的,并且总是相同的错误值。添加新记录后直接查看表会显示自动编号字段值与上述语句返回的值不同。

myLong = DLookup("AutoNumberField","TableName","SomeCriteria")

只要在 rs.Update 之后就可以正常工作,并且还有其他可以唯一标识记录的字段。

【讨论】:

我用 dao 插入了一个 SQL Server 表。这是唯一对我有用的东西。但我使用 DMax 而不是 DLookup。

以上是关于最后插入行的自动编号值 - MS Access / VBA的主要内容,如果未能解决你的问题,请参考以下文章

从 MS Access 中的表中获取自动编号字段值

无法通过 C# oledb 将记录插入 MS Access

MS Access ADP 自动编号

如何检索 MS-Access 中的最后一个自动增量值,例如 Sql Server 中的 @@Identity

MS Access:使用 VBA 进行 SQL 插入的日期格式

在压缩/修复期间防止自动编号重置 (MS Access)