39

主キーとして自動番号を使用するJETテーブルがありますが、行を挿入した後にこの番号を取得する方法を知りたいです。を使用して最も高い値の行を取得することを考えMAX()ましたが、これがどれほど信頼できるかはわかりません。いくつかのサンプルコード:

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

主キーの値を返さないため、これは機能しないことがわかりましたExecute()が、これは基本的に私が探している種類のコードです。新しい行の主キーを使用して、別のテーブルの行数を更新する必要があります。

これを行う最も簡単で読みやすい方法は何でしょうか?

4

5 に答える 5

52

あなたの例では、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

于 2009-10-27T20:07:22.940 に答える
41

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を持つ2つのテーブルを結合するaと、を検討します。SQL Serverの場合、プロパティを持つ別のテーブルにレコードを挿入するトリガーがあるかどうかを検討してください。IDENTITYINSERT INTOVIEWIDENTITY

ところで、レコードを挿入した直後で、関数の実行が終了DMaxする前に、他の誰かがレコードを挿入したかのようには機能しません。その場合、そのレコードを取得します。Dmax

于 2009-10-27T01:27:17.380 に答える
4

これは私のコードからの適応です。私はdeveloppez.comからインスピレーションを得ました(「 Pourinsérerdesdonnées、vaut-il mieux passer par un RecordSet ouparunerequêtedetypeINSERT? 」のページをご覧ください)。彼らは説明します(少しフランス語で)。この方法は、アッパーよりもはるかに高速です。この例では、この方法は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

于 2009-11-27T12:35:42.563 に答える
3
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
于 2014-08-06T20:22:50.160 に答える
1

すぐ上の両方の例は私にはうまくいきませんでした。テーブルでレコードセットを開いてレコードを追加すると、次の場合を除いて、レコードを追加できます。

myLong = CLng(rs!AutoNumberField)

rs.AddNewとrs.Updateの間に置くと、Nullを返します。rs.Updateの後に置くと、何かが返されますが、それは常に間違っており、常に同じ誤った値です。新しいレコードを追加した直後にテーブルを見ると、上記のステートメントによって返された値とは異なる自動番号フィールド値が示されています。

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

rs.Updateの後に実行され、レコードを一意に識別できる他のフィールドがある限り、正しく機能します。

于 2019-05-28T21:09:00.743 に答える