DOBON.NET DOBON.NETプログラミング掲示板過去ログ

1トランザクションでセレクトとデリート

環境/言語:[Vista, VB.Net, Framework 3.5]
分類:[.NET]

VB.Netにて1トランザクションでセレクトとデリートを行いたいのですが、
セレクト後にデリートを実行すると"DataReaderが既に開かれている"とエラーが発生してしまいます。

他のサイトにて
"DataReaderだけ閉じて、コネクションは閉じなければよい"
とあったのですが、DataReaderを閉じる方法が分かりません。

以下にコードを記述します。
DBはPostgreSQLです。

Dim connection As New OdbcConnection("コネクションストリング")
connection.Open()

Dim command As New OdbcCommand
command.Connection = connection

Dim transaction As OdbcTransaction
transaction = connection.BeginTransaction
command.Transaction = transaction

command.CommandText = strQuery
command.ExecuteReader()

@

command.CommandText = ""
command.ExecuteNonQuery()

transaction.Commit()
connection.Close()

@にDataReaderを閉じるコードを記述すればよいと判断しているのですが、
安直に
"command.ExecuteReader.Close()"
と記述したところ、@にて同じ内容のエラーが発生してしまいました。

色々調べたつもりなのですが、どうにも解決できません。
ご教授、もしくは参考になるサイトを教えて頂けませんでしょうか。

よろしくお願い致します。
■No24214に返信(ライムさんの記事)
> command.ExecuteReader()
ExecuteReader を呼び出したら、その戻り値となる DataReader を
変数に受け取るようにしてください。

データの読込操作は、その DataReader 変数を通じて行うことになります。
Close 処理も、その変数に対して行うよう変更してください。


> "command.ExecuteReader.Close()"

これだと、先の ExecuteReader とは別の DataReader を開きなおし、
それをすぐさま閉じようとしている事になってしまいます。

つまり、先に開いていた DataReader は放置されているため、
二重オープンとなってしまったわけですね。
申し訳ございません。
自分で解決してしまいました。

"command"がSQL文を実行しているのだから。
"command"が閉じるのだろうと思っていましたがそうではなく、
"ExecuteReader()"の戻り値をクローズするのですね。

そもそもサンプルコードに
"command.ExecuteReader()"の結果を
"odbcDataReader"に格納するコードを記述していないのも問題でした。

つまりコードは
(見直してみたらサンプルコード問題だらけですね…)
Dim odbcDataReader As OdbcDataReader
command.CommandText = "セレクト文"
odbcDataReader = command.ExecuteReader()

odbcDataReader.Close()

command.CommandText = "デリート文"
command.ExecuteNonQuery()

これで正常に動作しました。
皆様お騒がせ致しまして申し訳ございません。
解決済み!
魔界の仮面弁士さん

ありがとうございます。
解決のレスを記述してる途中にレスを頂いたようです。

全く魔界の仮面弁士さんのおっしゃる通りでした。
私の解決レスより全然分かりやすいですね。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板