主キーとして自動番号を持つ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
プロパティを持つ2つのテーブルを結合するIDENTITY
あなたも INSERT INTO
the 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 or par unerequêtede 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
ルシグネ
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の後に行われ、レコードを一意に識別できる他のフィールドがある限り、適切に機能します。