
おはようございます。
今回は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件)
- 最新から表示
- 回答順に表示
No.1
- 回答日時:
プログラムの造りが悪いです
行儀が悪いプログラムです。
ODBCSession ODBCCommand ODBCCommand2 をグローバルで定義して
(使いまわして)いるので、自分が使ったら、次の処理のためにそれぞれの
後始末をしてやる必要があります。
ArticleTableUpdate 以外でも使っているのであれば、そっちに問題が
あったときにどうしようもないです。
他人のふんどしを使っているというか、他人任せ、直前の処理に依存。
しかも依存する利点は無いという。。。
当の ArticleTableUpdate 内部の処理でもエラートラップされていないし、
処理が終わって New するくらいなら、自分が使う前にやればいいのに。
もしかしてこれを後始末だと思っているんでしょうか?
次の処理の準備までは出しゃばるけど、実際の処理までは面倒見れない
とか、余計なお世話でしかありません。
関数を分ける実力が無さそうなので、1つの関数で
・データベースに接続(インスタンスの生成からローカルで行い、グローバル
な変数を使わない)
・SQLで処理
・データベースから切断(接続を閉じた後、使ったインスタンスも破棄)
と行儀よくきちんと閉じるように、
最初から最後まで自分の関数内で面倒を見た方がいいのでは?
ありがとうございます。
確かに別の関数が原因でした。
元のプログラム(VB6)からのバージョンアップって事で、元のソースからこんなつくりでした(言い訳にしかならないですけど。)
エラートラップのは、別クラス?のを使いまわししていてvisual stduio2010で元のソースをアップグレードしたらエラーになった為にはずしただけです。
これで完成というわけではありません。(これも言い訳ですが。)
私はどちらかというと、動けば良いという考えの人間なので、行儀の良いとかはよくわかりません。
ちゃんとお金が発生するなら上の人・先輩等に聞きますが、発生しているわけではないので別にいいかなーと。
後でレビューした時に一杯言われますしね。
MARU4812さんがおっしゃったような事は少なからず言われるでしょうから、レビュー前に直します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
共通モジュールでDBへの接続と利用方法
Visual Basic(VBA)
-
「タイプ初期化子が例外をスローしました」エラー何?
Visual Basic(VBA)
-
複数SQL発行について
Visual Basic(VBA)
-
-
4
SPREAD(GrapeCity)のセルにフォーカスを設定するにはどうしたらいいのでしょうか?
Visual Basic(VBA)
-
5
日付型のフィールドに空白を入れる方法を教えてください
その他(データベース)
-
6
CloseとDisposeの違い
Visual Basic(VBA)
-
7
値を返さないコード パス
Visual Basic(VBA)
-
8
VB.NETで DataRow()を利用して、値からコードを取得したい。
Visual Basic(VBA)
-
9
GROUP BYを行った後に結合したい。
Oracle
-
10
VB.NETでのイベントの途中終了
Visual Basic(VBA)
-
11
フルパスから最後のディレクトリ名を取得したい。
Visual Basic(VBA)
-
12
「指定されたキャストは有効ではありません。」とエラーが出てしまいます。
Microsoft ASP
-
13
VB.NET2005 TextBox 高さ(Height) 変更
Visual Basic(VBA)
-
14
別フォームから戻ったときのイベント
Visual Basic(VBA)
-
15
String"から型'Double'への変換は無効です。 とエラーが出ます。
Visual Basic(VBA)
-
16
VB.NETの配列にExcelから読み込んできたデータを格納したい
Visual Basic(VBA)
-
17
SQLServer sqlcmdが使えない
SQL Server
-
18
フォームの再読み込み
Visual Basic(VBA)
-
19
GROUP BYでエラーが発生
SQL Server
-
20
DateTimePickerでに年月までしか選択できないようにしたいです。
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VB.NET DataReaderが開かれている
-
ボタンが活性化の場合とは、ボ...
-
腕時計の時報をならないように...
-
javascriptでセッションを取得
-
このadidasの腕時計の時刻の設...
-
Strutsのデータ受け渡しについて
-
Formatでmmが月と分を意味する理由
-
sessionスコープとapplication...
-
Perlで処理の進行状況をユ...
-
ServletとJSPで。。。
-
ActiveWorkbook.Pathの一つ下の...
-
漏電遮断器の黄色ボタンと白色...
-
グローバルIPアドレスの変更タ...
-
フォーム上で押されたボタンに...
-
VBScriptで「My Documents」フ...
-
XMLHTTPを使って、セッションID...
-
strutsで空白を認識させるには?
-
struts bean:defineについて
-
strutsを使ってテキストエリア...
-
リクエストに応じたselectedの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Formのデータが欠落することがある
-
VB.NET DataReaderが開かれている
-
C言語からデータベースにアクセス
-
dbからデータをとりだす際、sql...
-
JavaScriptとACCESSデータベー...
-
「XML over HTTP」「非同期HTTP...
-
DBNULLについて
-
三菱GOTの画面切り替えについて
-
ボタンが活性化の場合とは、ボ...
-
リクエストに応じたselectedの...
-
フォーム上で押されたボタンに...
-
Java-jspの画面入力値保持について
-
「<c:forEach タグが終了し...
-
VB6 開発環境のエディタに行...
-
jspからServletを呼び、元のjsp...
-
webアプリを作ってます。エラー...
-
腕時計の時報をならないように...
-
漏電遮断器の黄色ボタンと白色...
-
C言語で今まで表示していた画面...
-
グローバルIPアドレスの変更タ...
おすすめ情報