- - PR -
identityな列への登録と値取得を1命令で行う方法
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2005-09-19 00:07
ASP.Net初めて半月のPGです。
Webであるシステムのユーザーを管理するようなプログラムを作成しているのですが、 壁にぶつかっているので質問します。 処理としては以下の様なことを行おうと思っています。 1.利用者がフォームにデータを入力 2.該当ユーザのデータが存在しなければDBに新規登録 3.登録したデータのキー値を元にWebサーバにディレクトリを作成する。 ここで、DataAdapterを利用してidentityなキーを持つテーブルにデータを登録している のですが、DataAdapterがデータを更新したタイミングで新たに追加された値をとる 方法がわからず困っています。 データ登録後、改めて@@IDENTITYやSCOPE_IDENTITYや、キーの最大値を求めるSQLを 投げるという手も有りますが、登録→取得とアプリ側で処理を分けるとアプリ側で 排他制御をする必要があるため、信頼性が下がるのでこの方法はできれば遠慮したい ところです。 ADOのようにUpdateと同時に値を取得する方法をご存知の方はいらっしゃいませんで しょうか? 以下は現在「とりあえず動いている」ソースです。 ---------------------------------------------------- strKey = Session("UserNo") strSQL = "select * from M_User where UserID = @ID" Dim con As New SqlConnection(ConfigurationSettings.AppSettings.Get("g_ConStr")) con.Open() Dim cmd As New SqlCommand(strSQL, con) Dim da As New SqlDataAdapter() '☆ UserIDからユーザーを引っ張る Dim param As SqlParameter Dim ds As New DataSet() param = cmd.CreateParameter() param.ParameterName = "@ID" param.Value = strKey cmd.Parameters.Add(param) da.SelectCommand = cmd da.Fill(ds, "M_User") Dim dt As DataTable = ds.Tables("M_User") Dim dr As DataRow If dt.Rows.Count > 0 Then '該当データ発見! dr = dt.Rows(0) flgNew = False Else '☆ データが無いときは追加する。 dr = dt.NewRow() flgNew = True End If 〜〜〜以下、drにデータ設定〜〜〜 ・ ・ ・ 〜〜〜設定終了〜〜〜 If flgNew Then '☆ 新規追加の場合は行を追加する。 dt.Rows.Add(dr) End If Try Dim ret As Integer ret = da.Update(ds.Tables("M_User")) '☆本来ならこのUpdateを行った時点で登録したデータに入るIDがほしい。 If ret <> 1 Then '☆ 失敗! Exit Function End If Catch ex As SqlClient.SqlException Update = False Exit Function End Try Dim drs() As DataRow '☆ 登録した情報を元にデータを検索。 drs = ds.Tables("M_User").Select("UserID=" & Session("UserNo")) '☆IDENTITYな値取得! iPlanID = drs(0)("PlanID") 〜〜〜以下、ディレクトリを操作するコードが続く〜〜 DataRowの内容を取得元と同期するメソッドがあれば簡単に解決するのですが… [ メッセージ編集済み 編集者: どてかぼちゃ 編集日時 2005-09-20 11:25 ] | ||||
|
投稿日時: 2005-09-20 13:41
Updateと同時に取得はできないようなので@@identityの値を取得するようにしました。
@@identityは同一コネクション中で最後にinsertしたidentityな値を保持している らしいので排他制御を行わなくても自分がinsertを行ったレコードのidentityな項 目の値を保持している様でした。 ループで一気に複数件登録する場合など、Update毎にSelectを投げるのは 処理効率が悪そうですが… //ADOにできるのにADO.Netでできないというのは何か納得いかない物がありますが… [ メッセージ編集済み 編集者: どてかぼちゃ 編集日時 2005-09-20 13:55 ] | ||||
|
投稿日時: 2005-09-20 14:18
試していないけど.. da.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord; da.InsertCommand.CommandText = "INSERT INTO テーブル名 (列名) VALUES (値); SELECT * FROM テーブル名 WHERE (連番 = SCOPE_IDENTITY())"; 参考 http://www.microsoft.com/japan/msdn/library/ja/cpref/html/frlrfSystemDataCommonDataAdapterClassUpdateTopic.asp http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=21176&forum=7 | ||||
|
投稿日時: 2005-09-20 16:21
todo様
ご意見ありがとうございます。 実はSqlCommandBuilderを利用し、データセットから自動的にコマンドを生成 しているため、この方法は利用できませんでした。 Update前にコマンドビルダからInsertCommandのオブジェクトを取得し、 CommandTextプロパティに、Select句を追加してみたのですが、Updateの時点で SqlCommandBuilderが自動的にDataAdapterのCommandを更新してしまい、IDは 取得できませんでした。 残念ながら今回はもう一度クエリを投げて@@identityを取得しようと思います。 | ||||
|
投稿日時: 2005-09-20 16:55
http://dotnet247.com/247reference/msgs/12/61091.aspx
| ||||
|
投稿日時: 2005-09-20 17:42
todo様
私が躓いていた部分と全く同じ場所ですね。 的確なアドバイスありがとうございました。 |
1