none
データベースのテーブルに追加した行のIDを取得したい RRS feed

  • 質問

  • Id, Title, Description, Dateという列をもった「新着情報テーブル」をSQLに作成しました。Idは自動的に通し番号がつくようにIdentityをtrueにしてあります。

    そのテーブルにSQLコマンドで行を追加した場合、その追加した行のIdを取得したいのですがよい方法はないでしょうか?

    今は、一般的なやり方を知らないので、行を追加したあとにIdをもとに降順に並べ替えて一番最初のIdを取得しています。

    しかし、この場合、アクセスが集中したりして行の追加コマンドの実行と追加したIDの取得実行との間に、さらに行追加のコマンドが実行されたら違うIDが返ってくるのではないかと考えています。

    たとえば、次の内容を追加するとします。

    (Aとします)
    Title:新商品入荷しました。
    Description:ご覧ください。
    Date:2007/01/01

    と追加したとほぼ同時に、

    (Bとします)
    Title:営業時間のお知らせ
    Description:深夜まで営業してます。
    Date:2007/01/01

    が追加された場合、AのIDを取得しようと、ここで最新のIDを取得するとBのIDが返ってくることになります。

    同時に追加処理されることはほとんどないことですが、起こりうる問題ですので、どのようにしたら、追加したIDを取得することができるでしょうか?

    System.Data.SqlClient.SqlCommand.ExecuteNonQuery()でSQLコマンドを実行してますが返ってくるのは処理した行の数で、処理した行のIDを返す方法があればいいのですがないようなので、どのようにしたら実現できるか知恵をお貸しください。

    追加処理とID取得処理の間、他の追加処理が実行されないようにロックすることができるのかな?とも考えてますがどうなんでしょうか。それともほかに良い方法がありますでしょうか?

    わかりづらいとは思いますがよろしくお願いいたします。

    2007年3月8日 8:50

すべての返信

  • SQLServer ならストアドにして SCOPE_IDENTITY を戻すようにしてはどうでしょう。SQLServer2005なら ストアドにしなくても OUTPUT句でIDを戻せるのかなぁ

     

    2007年3月8日 8:59
  • 投稿ありがとうございます。

    ストアドプロシージャーについてですが、ホスティングサーバーで実装したいと考えているので、できるかどうか確認してみます。

    SQL Server 2005でOutput句というのがあるんですね。
    ちょっと調べてみます。

    他にも何か方法があったら教えてください。ありがとうございました。

    2007年3月8日 17:41
  • SELECT SCOPE_IDENTITY()は、現在のセッション(接続)における現在のスコープ(有効範囲)における最後の自動インクリメント値を返すので、

    sqlCommand1.CommandText = "select SCOPE_IDENTITY() as 'Identity'"

    などと、insert文に続けて実行してもOK。
    ちなみにスコープとは、バッチ、ストアドプロシージャ、トリガ、関数毎。

    2007年3月9日 3:18
    モデレータ
  • 自分はIdentityは使用しないで、専用の連番作成用テーブルを使ってます。もう何年にもなりますがトラブルは発生してません。

    新規番号を発行する時、連番作成用テーブルもロックされるので、微妙なタイミングでも動作は保障されます。

     

    2007年3月9日 7:32