- - PR -
SCOPE_IDENTITY取得について
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2009-02-05 18:29
開発言語:VC#2005
DB:SQLserver2005 いつもお世話になっています。 つい先日もお世話になったのですが、SCOPE_IDENTITYについて質問があります。 過去の書き込み等を参考にしたのですが分かりませんでした・。 テーブルに新規に行を追加し、その行の主キーでもあるIDENTITYの取得の仕方が分からず困っています。 そのIDENTITYの値を元に別テーブルにレコードを追加したいと考えています。 参考書等を参考にコードを書いてみたのですが、エラーが出てしまいます。
現在上記の様なコードを作っていて、newProdID = (Int32)sqlCmd.Parameters["@OrgID"].Value;の 部分でエラー”NullReferenceException がキャッチされました。オブジェクト参照がオブジェクト インスタンスに設定されていません。”が 出ています。 確かに”@OrgID”には値は入っていなくNULLでした。 何がおかしいのでしょうか? SQL文自体が違うのでしょうか? 申し訳ありませんが教えて下さい。 宜しくお願い致します。 | ||||||||||||
|
投稿日時: 2009-02-05 20:09
SqlCommandにSQL文とパラメータの設定している所まではOKだと思いますが、結果を取得するにはSQL文の発行が必要なのではないでしょうか?
SQL文を発行してからだと、
もうまくいくのではないかな〜っと思います。 ExecuteNonQuery とか ExecuteScalar あたりのヘルプ見てもらうといいかもです。 試しては無いので、はずしてたらごめんなさい。 | ||||||||||||
|
投稿日時: 2009-02-06 09:40
セラフ様回答ありがとうございます。
早速、ExecuteNonQuery、ExecuteScalarを調べExecuteScalarを使用してみました。
この様に変更しテストしてみたところ、IDENTITY値は取得できましたが、テーブルに同じ内容が 書き込まれてしまいました。 sqlCmd.ExecuteScalar();を実行した後でテーブルに書き込み、そしてda.Update(ds, "tblUke");の実行後にもう1回書き込み。 おそらくsqlCmd.ExecuteScalar()を実行した後でda.InsertCommand = sqlCmd;を したせいだとは思うのですが、これをda.Update(ds, "tblUke");を した時のみデータベースを更新するのはできないのでしょうか? 質問ばかりで申し訳ありませんが、お知恵をお貸し下さい。 宜しくお願い致します。 | ||||||||||||
|
投稿日時: 2009-02-06 10:22
IDENTITY の値は、SQL(INSERT)を実行した後でないと取得できません。
最初のコードでは、SQL実行前にIDENTITY値を取得しているのでエラーですね。 2回目のコードは、SQL実行 → 値取得 → SQL実行 していますね。 単純に、SQL実行 → IDENTITY値取得 するだけで良いのでは。 | ||||||||||||
|
投稿日時: 2009-02-06 10:42
た様回答ありがとうございます。
やはり二回SQL文を実行しているせいなのですか。
これでいきますと
で行っているSqlDataAdapterでデータベース更新は不要という事なのでしょうか?
この段階でデータベースも更新されているのは問題ないのでしょうか? まだまだ初心者で、da.InsertCommand→da.Update この流れでデータベースを更新すると思っている者ですから・・。 質問ばかりで申し訳ありませんが、宜しくお願い致します。 | ||||||||||||
|
投稿日時: 2009-02-06 11:48
SqlDataAdapter.Update
SqlCommand.Execute系 どちらでもSQLを実行できますが、 INSERTコマンドを実行するのであれば SqlCommand ですかね。 DataSetを使用した読み込み・更新の場合は、SqlDataAdapter。 今回はOUTPUTパラメータでIDENTITY値を取得しているので、 SqlCommand.ExecuteNonQuery() の実行でいいと思いますよ。 今後の為に、ExecuteNonQuery・ExecuteScalarの違い等も 理解しておいたほうがいいと思います。 | ||||||||||||
|
投稿日時: 2009-02-06 18:38
た様回答ありがとうございます。
ご指摘の通りにExecuteNonQuery()を実行し、SqlDataAdapterのUpdateはやめました。 すると、思い通りの事ができる様になりました。 でもちょっと気になる所があります。
この部分なのですが、実はプログラム上では両方使っています。
複数のテーブルをDatasetで取り込みDataRowに新しい行を追加し、データベースを追加・更新しています。 そのため、今まで、
でデータベース追加・更新していました。 このコードを使うにあたって、dt.Rows.Addも使用していました。 しかし、ExecuteNonQuery()を使う事により上記のコードは不要となっています。 以上の様に現状しているのですが、これが正しいのか間違っているのかえさえ分かっていません。 もし、指摘内容があるのなら教えて頂けないでしょうか? 初心者の質問の為、意味不明な点があるかとは思いますが、宜しくお願い致します。 | ||||||||||||
|
投稿日時: 2009-02-07 13:41
データの追加・更新をどの方法で行うかによりますが
1. DataAdapterを経由で行う。ex. DataAdapter.Update() 2. INSERT/UPDATEを自力で実行する。ex. SqlCommand.ExecuteNonQuery()等 DataSetありきのプログラムを書かれているならば、1.のほうがベターでしょう。 DataAdapter.Update()メソッドではInsertCommandプロパティ,UpdateCommandプロパティ,DeleteCommandプロパティに設定されたSqlCommandが内部で実行されます。 DataSet/DataAdapterの役割について整理されるとスッキリして行くと思います。 |