3

非常によくある質問ですが、最後に挿入されたレコードの ID を取得できません。ODBC リンク テーブルで DAO を使用して、レコードと子レコードを複製しています。私のテーブルは SQL Server 2008 にあり、ID フィールドの ID フィールドがあります。

これが私がこれまでに試したことです。ここでのコードの最初のビットは、エラー 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

次に試したことは次のとおりです。

Debug.Print db.OpenRecordset("SELECT @@identity FROM item")(0)

この最後のものは問題なく完了しますが、返される値は正しくありません。実際の新しい 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")
4

4 に答える 4

6

私の知る限り@@IDENTITY、カーソルベースの挿入では機能しません。DAO と ADO は両方とも、バックグラウンドでカーソルを使用します。

レコードを取得したら.Update、値を読み取るだけで ID 値を取得できるはずです。

以下は、キーセット セマンティクスで開かれた ADO レコードセットを介してうまく機能します。

r.Update
Debug.Print r("ItemID")

Dynaset セマンティクスで開かれた DAO レコードセットを介して、次のように動作します。

r.Update
r.Bookmark = r.LastModified
Debug.Print r("ItemID")

と を避ける必要が.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")
于 2012-06-06T00:18:19.373 に答える
0

SQLサーバーバックエンド(マルチユーザーアプリ内)では機能しません。アクセステーブルの場合、SQL使用ストアドプロシージャで機能します。この方法を使用します

CREATE PROCEDURE dbo.AddAsset

  @Name VARCHAR(500),
  @URL  VARCHAR(2000),
  @new_identity INT = NULL OUTPUT
AS
BEGIN
    SET NOCOUNT ON;

INSERT dbo.Assets(Name, URL) SELECT @Name, @URL;
SET @new_identity = SCOPE_IDENTITY();

END 
GO

次に、このspをフロントエンドで使用します

于 2015-03-29T18:11:44.637 に答える
-1

Updateステートメントを実行する前に、キー フィールドの値を取得するだけです。以下のコメントで指摘されているように、Microsoft Access とは異なるバックエンドを使用している場合、このプロセスは機能しません。しかし、それがあなたのユースケースであり、最後に挿入されたレコードの ID を取得する方法に関する一般的な質問への回答を探しているだけの場合に備えて、この回答をここに残しておきます。

あなたの例では、Microsoft Access でこれを行うことができます。

Dim r as DAO.Recordset, db as DAO.Database
Dim lKey As Long
Set db = CurrentDb
Set r = db.OpenRecordset("SELECT TOP 2 * FROM item ORDER BY DateTimeModified DESC", dbOpenDynaset, dbSeeChanges)
r.AddNew
    'Set field values here
    'Retrieve the key value before executing the Update
    lKey = r!ItemID
r.Update
Debug.Print lKey
于 2012-12-24T22:03:28.123 に答える