- PR -

SQLSERVER2000で IDENT_CURRENT と @@IDENTITY と SCOPE_IDENTITY の違い

1
投稿者投稿内容
McLaren
ぬし
会議室デビュー日: 2002/01/15
投稿数: 784
お住まい・勤務地: 東京
投稿日時: 2005-09-28 20:35
 いつもお世話になっております。
SQLSERVER2000+Access2000を使っております。

二つのテーブルがあります。

[テーブル t1]
s_id(int型 主キー Identityで自動採番)
s_name
s_passwd

[テーブル t2]
s_id(int型 主キー)
a_id(int型 主キー)
a_data

ここで、VBA側からADOでDBに接続し、t1にデータを一件追加します。
するとs_idがIdentityであることから新規にIDが振られます。

そして直後に、s_idはこのIDを使ってa_idとa_dataをVBAで生成してt2にデータをINSERTします。またこれらをトランザクションをつかって

.BeginTrans
〜(.RollBack)
.Commit

のように一連の処理にしようと思っております。(訳あってトリガは使えません)

 ここで、t1で振られたs_idをt2にも使うという方法で何が一番良いのでしょうか。。
今のところ

IDENT_CURRENT
@@IDENTITY
SCOPE_IDENTITY

のどれかを使おうと思っているのですが、ヘルプを見ても違いがよくわかりません。本件の場合どれを使うのが良いのでしょうか。何卒ご教授願います。
TLC
大ベテラン
会議室デビュー日: 2005/05/31
投稿数: 152
お住まい・勤務地: 東京都
投稿日時: 2005-09-29 00:37
引用:

McLarenさんの書き込み (2005-09-28 20:35) より:

IDENT_CURRENT
@@IDENTITY
SCOPE_IDENTITY

のどれかを使おうと思っているのですが、ヘルプを見ても違いがよくわかりません。本件の場合どれを使うのが良いのでしょうか。


お疲れ様です。

今回のシナリオですと,

@@IDENTITY と SCOPE_IDENTITY に違いはないと思います。
(トリガを使用しないということですので)

ただし,IDENT_CURRENT は使用できないと思います。
IDENT_CURRENT ですと,セッションに関わらず特定テーブルの最終 IDENT を拾ってしまうので,(未コミットの IDENT も含めて)
トランザクションが平行して走った場合に隣の IDENT をとってしまうことになるでしょう。

もし,今後トリガも併発するようでしたら,
正解は,SCOPE_IDENTITY となると思います。
(実際に INSERT でとった IDENT を拾うので)

あとは適切な箇所で SCOPE_IDENTITY を発行するだけです。

----------
TimberLandChapel
http://blogs.timberlandchapel.com/blogs/timberlandchapel/
McLaren
ぬし
会議室デビュー日: 2002/01/15
投稿数: 784
お住まい・勤務地: 東京
投稿日時: 2005-09-29 09:00
わかりやすいご教授、本当にありがとうございました。

Transact-SQL リファレンス によると

SCOPE_IDENTITY
同じ有効範囲内の IDENTITY 列に挿入された最後の IDENTITY 値を返します。有効範囲はモジュール、つまりストアド プロシージャ、トリガ、関数、またはバッチです。このため、2 つのステートメントが同じストアド プロシージャ、関数、またはバッチにある場合、その有効範囲は同じです。

とありますが、VBAからADOで接続する場合の「有効範囲」というのは、具体的にはどこからどこまでのことを指しますでしょうか。。

(セッションはADODB.Connection を.Openしてから.Closeするまでのことだと思っています。)

何卒ご教授よろしくおねがいいたします。
TLC
大ベテラン
会議室デビュー日: 2005/05/31
投稿数: 152
お住まい・勤務地: 東京都
投稿日時: 2005-09-29 10:39
引用:

McLarenさんの書き込み (2005-09-29 09:00) より:

とありますが、VBAからADOで接続する場合の「有効範囲」というのは、具体的にはどこからどこまでのことを指しますでしょうか。。



お疲れ様です。

この辺は,ローカライズによる弊害ですよね。。
原文を参照した方が話がわかりやすいです。

「有効範囲」とは「スコープ」のことです。
ここで言うスコープは T-SQL 上のスコープのことですので,
ADO か直接クエリであるかということに関係なく,T-SQL 内部でのスコープになります。

T-SQL 上でのスコープは,モジュールの単位で,
・ストアドプロシージャ
・トリガ
・関数
・バッチ
となります。
ADO から投げるひとかたまりのクエリは,途中でストアドを呼ぶなどしなければ,
単一のバッチスコープの中に入ることになります。

[参考]
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_sa-ses_6n8p.asp

----------
TimberLandChapel
http://blogs.timberlandchapel.com/blogs/timberlandchapel/
McLaren
ぬし
会議室デビュー日: 2002/01/15
投稿数: 784
お住まい・勤務地: 東京
投稿日時: 2005-09-29 11:20
ありがとうございます。

では例えば

(ここからがスコープ始まり?)
rs.Source = "t3"
rs.Open
rs.AddNew
rs![Fld1] = xxxx
rs![Fld2] = xxxx
rs![Fld3] = xxxx
rs.Update
rs.Close
(ここでスコープ終わり?)

の流れの中で

"SELECT SCOPE_IDENTITY() as [SCOPE_IDENTITY]"
の結果を得ようと思うとどのように書くことができますでしょうか。。。


trapemiya
大ベテラン
会議室デビュー日: 2005/07/30
投稿数: 102
投稿日時: 2005-09-29 12:13
ここら辺も参考になるかと。

@@IDENTITY クライシスを管理する
http://www.microsoft.com/japan/msdn/net/adonet/manidcrisis.asp
McLaren
ぬし
会議室デビュー日: 2002/01/15
投稿数: 784
お住まい・勤務地: 東京
投稿日時: 2005-10-04 18:27
ありがとうございました!
1

スキルアップ/キャリアアップ(JOB@IT)