アプリ版:「スタンプのみでお礼する」機能のリリースについて

おはようございます。
今回はVB.NETについて質問させてください。

【開発環境】
・VB.NET(Visual Studio2010)
・PostgreSQL8.3
・WindowsXP

【質問内容】
ある一定の操作をすると、
『この Command に関連付けられている DataReader が既に開かれています。このコマンドを最初に閉じる必要があります』
とエラーが出てしまい、例外で落ちてしまいます。

【落ちる原因の操作】
1.メインフレームを起動
2.親品番マスタから取得した親品番一覧を表示しているListViewの1件をダブルクリック
3.親品番に紐付いている子品番を品番テーブルから取得
4.表示内容の切り替えラジオボタンを全て⇒図面ありに変更
5.表示内容の切り替えラジオボタンを図面あり⇒全てに変更
6.表示内容の切り替えラジオボタンを全て⇒図面ありに変更
7.表示内容の切り替えラジオボタンを図面あり⇒全てに変更←ここで先ほどの例外が発生する。

【該当部分のソース】
Private Sub ArticleTableUpdate(ByVal sParents As String)
Dim articleResult As Odbc.OdbcDataReader ' 品番テーブル用
Dim articleSql As String
Dim zumenSql As String
Dim sChild As String
Dim articleCount As Integer
Dim zumenCount As Integer
Dim zumenFlag As String

' 品番テーブルからデータを取得するSQLを作成
articleSql = "SELECT * FROM ""ARTICLE_TBL"" WHERE ""P_ARTICLE_NUMBER"" = '" + sParents + "'"
Debug.WriteLine("【ArticleTableUpdate】 品番テーブルからデータを取得SQL:" + articleSql)
ODBCCommand.CommandText = articleSql
' 品番テーブルから該当の親品番のデータ件数を取得
'articleCount = ODBCCommand.ExecuteNonQuery()

' 品番テーブルに該当の親品番のデータが存在するか
'If articleCount = 0 Then
'Exit Sub
'End If

' 品番テーブルから該当の親品番のデータを取得
articleResult = ODBCCommand.ExecuteReader() ←ここで例外発生

' 取得した件数分処理
While articleResult.Read()
' 子品番データを取得
sChild = articleResult("C_ARTICLE_NUMBER").ToString
If sChild <> "" Then
' 子品番データをキーに図面マスタからデータを取得するSQLを作成
zumenSql = "SELECT * FROM ""ZUMEN_MST"" WHERE ""PLAN_NUMBER"" = '" + sChild + "'"
Else
sParents = articleResult("P_ARTICLE_NUMBER").ToString
zumenSql = "SELECT * FROM ""ZUMEN_MST"" WHERE ""PLAN_NUMBER"" = '" + sParents + "'"
End If

Debug.WriteLine("【ArticleTableUpdate】 図面マスタからデータを取得SQL:" + zumenSql)
ODBCCommand2.CommandText = zumenSql
' 図面マスタから該当の品番のデータの件数を取得
zumenCount = ODBCCommand2.ExecuteNonQuery

' 図面マスターに該当の品番のデータが存在するか
If zumenCount = 0 Then
' 図面データが存在しない為、更新値を0とする
zumenFlag = "0"
Else
' 図目データが存在する為、更新値を1とする
zumenFlag = "1"
End If

' 品番テーブルを更新するSQLを作成
zumenSql = "UPDATE ""ARTICLE_TBL"" " + vbCrLf + "SET " + vbCrLf +
vbTab + """C_ARTICLE_NUMBER"" = '" + sChild + "', " + vbCrLf +
vbTab + """PLAN_FLAG"" = '" + zumenFlag + "', " + vbCrLf +
vbTab + """UPDATE_DATE"" = '" + Today + "'" + vbCrLf +
"WHERE ""P_ARTICLE_NUMBER"" = '" + sParents + "'"

Debug.WriteLine("【ArticleTableUpdate】 品番テーブルを更新するSQL:" + zumenSql)
ODBCCommand2.CommandText = zumenSql
' 品番テーブルを更新
zumenCount = ODBCCommand2.ExecuteNonQuery()
End While

articleResult.Close()
ODBCCommand = New Odbc.OdbcCommand
ODBCCommand.Connection = ODBCSession
End Sub

【DB接続関数】
Public Function ODBC_CONNECT() As Boolean

' 戻り値をセット
ODBC_CONNECT = False

If ConnectFlag = False Then
Try
ODBCSession = New Odbc.OdbcConnection
ODBCCommand = New Odbc.OdbcCommand
ODBCCommand2 = New Odbc.OdbcCommand

' データベース接続情報
ODBCSession.ConnectionString = "Provider=MSDASQL;DSN=HOGE;UID=hogeU;PWD=hogeP;"
ODBCCommand.Connection = ODBCSession
ODBCCommand2.Connection = ODBCSession

' データベースに接続
ODBCSession.Open()

ConnectFlag = True
ODBC_CONNECT = True
Catch
Debug.WriteLine("えらー")
End Try

End If
End Function

今のところ、このエラーが発生した場合、再起動すると発生しなくなるみたいです。(たまたまそうなったのかもしれません)

何か原因がわかる方、ご教授お願い致します。

A 回答 (1件)

プログラムの造りが悪いです


行儀が悪いプログラムです。

ODBCSession ODBCCommand ODBCCommand2 をグローバルで定義して
(使いまわして)いるので、自分が使ったら、次の処理のためにそれぞれの
後始末をしてやる必要があります。
ArticleTableUpdate 以外でも使っているのであれば、そっちに問題が
あったときにどうしようもないです。
他人のふんどしを使っているというか、他人任せ、直前の処理に依存。
しかも依存する利点は無いという。。。

当の ArticleTableUpdate 内部の処理でもエラートラップされていないし、
処理が終わって New するくらいなら、自分が使う前にやればいいのに。
もしかしてこれを後始末だと思っているんでしょうか?
次の処理の準備までは出しゃばるけど、実際の処理までは面倒見れない
とか、余計なお世話でしかありません。

関数を分ける実力が無さそうなので、1つの関数で
・データベースに接続(インスタンスの生成からローカルで行い、グローバル
 な変数を使わない)
・SQLで処理
・データベースから切断(接続を閉じた後、使ったインスタンスも破棄)
と行儀よくきちんと閉じるように、
最初から最後まで自分の関数内で面倒を見た方がいいのでは?
    • good
    • 0
この回答へのお礼

ありがとうございます。

確かに別の関数が原因でした。
元のプログラム(VB6)からのバージョンアップって事で、元のソースからこんなつくりでした(言い訳にしかならないですけど。)

エラートラップのは、別クラス?のを使いまわししていてvisual stduio2010で元のソースをアップグレードしたらエラーになった為にはずしただけです。
これで完成というわけではありません。(これも言い訳ですが。)

私はどちらかというと、動けば良いという考えの人間なので、行儀の良いとかはよくわかりません。
ちゃんとお金が発生するなら上の人・先輩等に聞きますが、発生しているわけではないので別にいいかなーと。
後でレビューした時に一杯言われますしね。

MARU4812さんがおっしゃったような事は少なからず言われるでしょうから、レビュー前に直します。

お礼日時:2011/08/03 13:17

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A