我有一个带有自动编号作为主键的JET
表,我想知道如何在插入行后检索此数字。我曾想过使用MAX()
来检索具有最高值的行,但我不确定这将是多么可靠。一些示例代码:
Dim query As String
Dim newRow As Integer
query = "INSERT INTO InvoiceNumbers (date) VALUES (" & NOW() & ");"
newRow = CurrentDb.Execute(query)
现在我知道这不起作用,因为Execute()
不会返回主键的值,但这基本上是我正在寻找的那种代码。我将需要使用新行的主键来更新另一个表中的多个行。
这样做最简单/最易读的方法是什么?
如果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 INTO
表示VIEW
。对于SQL Server,请考虑是否有触发器将记录插入另一个也具有IDENTITY
属性的表中。
BTW DMax
不会像其他人在你插入一个记录之后插入一个记录,但是在你的Dmax
功能完成之前,那么你就会得到他们的记录。
在您的示例中,因为您使用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来进行INSERT,但这里的效率要高得多。请注意,它不需要ADO
。
这是我的代码改编。我受到了developpez.com的启发(在页面中查找:“Pourinsérerdesdonnées,vaut-il mieux passer par un RecordSet ou parunerequêtedetype 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
LeCygne
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
上面的两个例子都不适用于我。在表上打开记录集并添加记录确实可以添加记录,除了:
myLong = CLng(rs!AutoNumberField)
如果放在rs.AddNew和rs.Update之间,则返回Null。如果放在rs.Update之后,它会返回一些东西,但它总是错误的,并且始终是相同的错误值。添加新记录后直接查看表显示自动编号字段值不同于上述语句返回的值。
myLong = DLookup("AutoNumberField","TableName","SomeCriteria")
只要在rs.Update之后完成,并且还有任何其他字段可以唯一标识记录,它将正常工作。