- PR -

SqlCommand、SqlDataReaderの使い回し(使いまわし)

投稿者投稿内容
使えないPL
会議室デビュー日: 2006/04/11
投稿数: 5
投稿日時: 2006-10-25 14:01
こんにちわ。2度目の投稿となります。
Microsoft Visual Basic .NET(2003)にて開発を行っております。
DBアクセスをSqlCommand,SqlDataReaderの使い回しがNGという噂を耳にしました。
一つの関数内にて同一オブジェクトの使い回しはNGなのでしょうか?
いろいろ調べたのですが答えが見付からず難儀しております。
少なくともSqlCommandが使い回せなかったらSqlTransactionの
意味が無いのでは、と思うのですが。。。
サンプルコードを記載してみました。(SQL命令自体には意味がありません)
突っ込みどころ満載のこのコードを、正しいコードに導いてやって下さいませ。
赤ペンレビューお待ちしております。

Private Sub test()
 Dim cn As SqlConnection
 Dim cm As SqlCommand
 Dim tr As SqlTransaction
 Dim re As SqlDataReader

 Dim strcn As String = "接続文字列"
 Dim strSql As String
 Dim wk1 As String
 Dim wk2 As String

 Try
  cn = New SqlConnection(strcn)
  cn.Open()
  tr = cn.BeginTransaction()
  cm = New SqlCommand
  cm.Connection = cn
  cm.Transaction = tr

  strSql = "select FLD1 from TBL1 where FLD1 = DATA1"
  cm.CommandText = strSql
  re = cm.ExecuteScalar()
  wk1 = re("FLD1")
  re.Close()

  strSql = "select FLD2 from TBL2 where FLD2 = DATA2"
  cm.CommandText = strSql
  re = cm.ExecuteScalar()
  wk2 = re("FLD2")
  re.Close()

  strSql = "update TBL3 set FLD3 = DATA3 + 1 where FLD3 = DATA3"
  cm.CommandText = strSql
  ret = cm.ExecuteNonQuery()

  strSql = "update TBL4 set FLD4 = DATA4 + 1 where FLD4 = DATA4"
  cm.CommandText = strSql
  ret = cm.ExecuteNonQuery()

  tr.Commit()

 Catch ex As Exception
  tr.Rollback()
  Throw ex

 Finally
  If Not IsDataNone(tr) Then
   tr.Dispose()
  End If
  If Not IsDataNone(re) Then
   re.Close()
  End If
  If Not IsDataNone(cm) Then
   cm.Dispose()
  End If
  If Not IsDataNone(cn) Then
   cn.Close()
  End If

 End Try

End Sub


[ メッセージ編集済み 編集者: 使えないPL 編集日時 2006-10-25 14:06 ]

[ メッセージ編集済み 編集者: 使えないPL 編集日時 2006-10-26 13:30 ]

[ メッセージ編集済み 編集者: 使えないPL 編集日時 2006-10-26 14:25 ]
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2006-10-25 14:24
引用:

使えないPLさんの書き込み (2006-10-25 14:01) より:
一つの関数内にて同一オブジェクトの使い回しはNGなのでしょうか?


特に問題ないと思います。が、

引用:

少なくともSqlCommandが使い回せなかったらSqlTransactionの
意味が無いのでは、と思うのですが。。。


これは関係ないでしょう。SqlCommandオブジェクトが別々でもトランザクションを
一緒にすることはできます。SqlCommandの使い回しをするシチュエーションというと、
同一のSQLによるパラメータクエリでパラメータを変えながら実行するというのが思い
浮かびます。
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2006-10-25 14:29
http://msdn2.microsoft.com/ja-jp/library/system.data.sqlclient.sqlcommand.aspx
SqlCommandに関しては↑ここに
「CommandText プロパティをリセットして、SqlCommand オブジェクトを再利用できます。ただし、新規コマンドまたは以前のコマンドを実行する前に、SqlDataReader を閉じる必要があります」
と書いてありますよ。SqlDataReaderはSqlCommandが生成するから使いまわしも何もないでしょう。

引用:
DBアクセスをSqlCommand,SqlDataReaderの使い回しがNGという噂を耳にしました。

どういった理由でNGなのですか?噂の出元(ソース)は?

引用:
サンプルコードを記載してみました。(SQL命令自体には意味がありません)

SqlDataReaderは使われていないようですが。。
さかもと
ぬし
会議室デビュー日: 2004/05/14
投稿数: 586
投稿日時: 2006-10-25 14:39
さかもとと申します。

DataReaderではなくConnectionの使いまわしのことではないでしょうか?
Connectionの使いまわしはどうしたら?ということで以前こちらに投稿
したことがあります。


Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-10-25 22:31
引用:

コード:
Catch ex As Exception
    tr.Rollback()
    Throw ex




 ex を使わないのなら、宣言しない。
 Throw ex とすると、上位でキャッチするとき、例外の発生場所がこの行になる。これではデバッグの時に困難になる。
コード:
Catch
    tr.Rollback()
    Throw



 AnalysisDirect ってなに?
_________________
使えないPL
会議室デビュー日: 2006/04/11
投稿数: 5
投稿日時: 2006-10-26 14:21
皆様ご回答ありがとうございます。
 
UK様
引用:
-------------------------------------------------------------------------------
これは関係ないでしょう。SqlCommandオブジェクトが別々でもトランザクションを
一緒にすることはできます。SqlCommandの使い回しをするシチュエーションというと、
同一のSQLによるパラメータクエリでパラメータを変えながら実行するというのが思い
浮かびます。
-------------------------------------------------------------------------------
ご指摘の通りでした。
SqlTransaction はSqlCommand をDispose しても影響が無いようです。
SqlTransaction はSqlConnection に紐付くのですね。
 
べる様
引用:
-------------------------------------------------------------------------------
どういった理由でNGなのですか?噂の出元(ソース)は?
-------------------------------------------------------------------------------
出元を探したのですが、発見に至りませんでした。
今後不用意な発言に注意いたします。
 
引用:
-------------------------------------------------------------------------------
「CommandText プロパティをリセットして、SqlCommand オブジェクトを再利用できます。ただし、新規コマンドまたは以前のコマンドを実行する前に、SqlDataReader を閉じる必要があります」
-------------------------------------------------------------------------------
しっかり書いてありますね。習ってCommandTextのみ上書きして実施しました。
ちなみにこの時はSqlCommand.Parameters.Add("item")を行っており
itemの重複で例外が起きたりしましたが問題ないようです。
SqlCommand.Parameters.Clear()を実施する事により回避しました。
 
さかもと様
いえ、やはり私が引っかかっているのはSqlCommand、SqlDataReaderの使い回しについてです。
 
Jitta様
例外処理のご指摘ありがとう御座います。今後のレビュー観点に追加させて頂きます。
すみません。名前空間です。紛らわしいので削除しておきます。
 
皆様ご回答ありがとう御座いました。
SqlCommandは使い回しが可能である。という結論で〆させて頂きます。

[ メッセージ編集済み 編集者: 使えないPL 編集日時 2006-10-26 14:24 ]
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-10-26 15:00
引用:

使えないPLさんの書き込み (2006-10-26 14:21) より:

べる様
引用:
-------------------------------------------------------------------------------
どういった理由でNGなのですか?噂の出元(ソース)は?
-------------------------------------------------------------------------------
出元を探したのですが、発見に至りませんでした。
今後不用意な発言に注意いたします。


よく、ひとつのブロックにて同じ変数を使いまわすのはよくないと言いますよね。
そういうことでは無いのでしょうか?

コード:
int i;
for (i = 0; i < 10; i++) {
   ・・・・
}
for (i = 10; i < 20; i++) {
   ・・・・
}
こういうのは良くない、下の for は別の変数を使用するべきだ。


みたいな(^^;)
_________________
R・田中一郎 -  R.Tanaka.Ichiro’s Blog
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-10-26 15:01
引用:

使えないPLさんの書き込み (2006-10-25 14:01) より:

DBアクセスをSqlCommand,SqlDataReaderの使い回しがNGという噂を耳にしました。


ローカル スコープ内であれば、あまり問題にはならないでしょう。
(ラッパークラス以外で) プライベート以上のメンバである場合は、バグの温床になります。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌

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