Insertした直後にIDが知りたい

解決


知里リン  2006-09-08 06:37:35  No: 133137

VB2005。Access-JET。新人です。よろしくお願いします。
Insertで新規データを登録します。IDはオートナンバーで取ってます。
新たにデータを登録したときに、わざわざSelect Max(id)とやらないで、
インサート直後に新規生成されたIDを取得する方法はありますか?


魔界の仮面弁士  2006-09-08 18:18:48  No: 133138

@@IDENTITY変数が利用できます。
http://yaplog.jp/orator/archive/12

上記は VB6 向けコードなので、VB2005 的に書きなおすとすれば、
こういう感じになりますね。

Public Shared Function GetIdentity(ByVal con As OleDbConnection) As Integer
  Dim cmd As New OleDbCommand("SELECT @@IDENTITY", con)
  Return CInt(cmd.ExecuteScalar())
End Function


知里リン  2006-09-09 22:42:41  No: 133139

魔界の仮面弁士さん、教えて頂いてありがとうございました。
Select Max(id)とやってもあまり変わらないのと、後で見たときに
何をやってるのかわかるので、Select Max(id)を使うことにしました。
ありがとうございました。


魔界の仮面弁士  2006-09-11 18:27:34  No: 133140

http://support.microsoft.com/kb/232144/en-us

> Select Max(id)とやってもあまり変わらないのと
変わらないとすれば、それは限定された条件下においてのみだったりします。(^^;

その「限定された条件」でしか使わない、というのであれば無理強いはしませんが、
MAX で取得した場合は、たとえば複数ユーザーあるいは異なる接続から更新された場合や、
あるいはオートナンバー列の設定状態などといった、条件如何によって、
@@IDENTITY とは異なる値が返される可能性が十分にありえる事は留意しておいてください。

どうしても MAX で行いたいという事であれば、せめて(共有モードではなく)
排他モードで開いた上で、かつ、"Jet OLEDB:Transaction Commit Mode" で
キャッシュを無効化した上で利用されることをおすすめします。


知里リン  2006-09-16 21:34:28  No: 133141

魔界の仮面弁士さん、返答ありがとうございました。私の方で勝手に
「解決」として」片付けてしまったので、掲示板を見ていませんでした。
こんな貴重なご意見を頂いていたとは知りませんでした。申し訳ありません。

私のやろうとしていたことは以下のようなことです。
1)売上明細データを登録(オートナンバーで)して、
2)確認のために再表示する際、IDで明細データを検索して表示知る
というものです。
この処理に対して、2つのアプローチがあると思います。

(1)オートナンバーで登録して、直後に登録したIDを取得して、取得したIDで
検索し、表示する。
(2)MAX IDを調べて、その「MAX ID+1」をインサートのIDにすると同時に
再表示用検索のIDとする

これらを行う条件として、この処理は年間2千件くらいで、1日最大でも
100件程度の処理です。2または3人で並行処理します。
この条件と、(2)はこれまでにも使ったことがあるので、結局この方法にしようと考えましたが、
全体をご判断頂いて、魔界の仮面弁士さん、再度ご意見を頂けないでしょうか。
よろしくお願いします。


魔界の仮面弁士  2006-09-18 12:50:34  No: 133142

> (1)オートナンバーで登録して、直後に登録したIDを取得して、取得したIDで
> 検索し、表示する。
> (2)MAX IDを調べて、その「MAX ID+1」をインサートのIDにすると同時に
> 再表示用検索のIDとする

前者(自動採番)だと、メンテナンス上、都合が悪い場合もあるかと思います。
後者(手動採番)だと、同時実行時の制御などといった手間が増加するでしょう。
なので最終的にどちらが良いかは、好みの問題のような気がします。

ただし個人的には、後者の方法をお奨めします。その理由としては、Jet の
一部の Service Pack バージョンによっては、mdb の最適化処理によって、
オートナンバーの初期値がリセットされてしまう事象が報告されているからです。

> 再度ご意見を頂けないでしょうか。
どういう方向の意見を求めておられるのでしょうか? (^^;

後者の方法に関して言えば、既に実装経験があるという事のようですし、
前者の実装だとすれば、先の回答にある方法で取得できるかと思いますので、
特に私の方から特に付け加える点も無さそうですけれども。

……とりあえず、Jet という事で、同時実行制御時に必須となるであろう
トランザクションとキャッシュ制御に関する資料だけ示しておきますね。
http://www.canalian.com/workshop/access/JetCache.html


※返信する前に利用規約をご確認ください。




  


  このエントリーをはてなブックマークに追加