- - PR -
ado.net ループ時のinsertについて
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2004-02-04 13:08
いつもお世話になってます。
ループをしながらあるテーブルへ書込みする時について教えて下さい。 下記の様にループ文を作成し,テーブルへデータ追加をしています。 ここまでは,特に問題ないのですが,その後,SELECT文で同じテーブルへ SELECTをかけるとどうやら,つかんでいる様でタイムアウトで おちてしまいます。どうやったら開放できるのでしょうか? ちなみに,違うテーブルでSELECT文を発行するのはうまくいきます。 For shtI = 1 To 10 If strTEST1(shtI) <> "" Then strSQL = "" strSQL = "INSERT INTO TEST (TEST1,TEST2) " strSQL = strSQL & "VALUES('" & strTEST1(shtI) & "'," & shtTEST2 & ")" Else strSQL = "INSERT INTO TEST (TEST1,TEST2) " strSQL = strSQL & "VALUES(NULL," & shtTEST2 & ")" End If Try 'SQL文設定 objSQLCommand.CommandText = strSQL objSQLCommand.CommandTimeout = TIMEOUT objSQLCommand.ExecuteNonQuery() Catch ex As SqlClient.SqlException Return False End Try Next objSQLReadCommand = objReadConnect.CreateCommand objSQLReadCommand.Connection = objReadConnect strSQL = "" strSQL = "SELECT * FROM TEST" Try objSQLReadCommand.CommandText = strSQL objSQLReader = objSQLReadCommand.ExecuteReader() Catch ex As SqlClient.SqlException Return False End Try objSQLReader.Close() | ||||
|
投稿日時: 2004-02-04 13:20
投げられたExceptionのMessageはどうなってますか?
それが解決のヒントになるかと。 あと、色々な識別子が出てきていますが、型がよくわかりません。 ソースの一部分をそのままコピペしただけのようですけど。 | ||||
|
投稿日時: 2004-02-04 13:49
レスありがとうございます。
ExceptionのMessageは タイムアウトに達しました。操作が完了する前にタイムアウト期間が過ぎたか、またはサーバーが応答していません。です。 ちなみにSELECT文前のINSERTをコメントにすると問題なく 処理を行います。 Dim objConnect As SqlClient.SqlConnection Dim objSQLCommand As SqlClient.SqlCommand Dim objReadConnect As SqlClient.SqlConnection Dim objSQLReadCommand As SqlClient.SqlCommand Dim objSQLReader As SqlClient.SqlDataReader ちなみに同じ様な事象の方のメーリングリストを見つけたのですが 結局回避方法がわからない状態です http://www.gdncom.jp/general/bbs/ShowPost.aspx?PostID=2407 | ||||
|
投稿日時: 2004-02-04 13:57
objSQLCommandはコネクションとしてobjConnectを、
objSQLReadCommandはコネクションとしてobjReadConnectを使っているということですね? (objConnectはソースには出てきませんが) objConnectをクローズしてからDataReaderを取得したらどうなります? | ||||
|
投稿日時: 2004-02-04 14:17
お世話になってます。
>objConnectをクローズしてからDataReaderを取得したらどうなります? うまくSELECT文を発行してくれましたが,DBをクローズしてしまったので その後の処理のINSERT文で失敗です。 どうやって回避すればよろしいでしょうか? >objSQLCommandはコネクションとしてobjConnectを、 >objSQLReadCommandはコネクションとしてobjReadConnectを使っているということですね>? >(objConnectはソースには出てきませんが) すいません。 Dim objConnect As SqlClient.SqlConnection Dim objTran As SqlClient.SqlTransaction Dim objSQLCommand As SqlClient.SqlCommand Dim objReadConnect As SqlClient.SqlConnection Dim objSQLReadCommand As SqlClient.SqlCommand Dim objSQLReader As SqlClient.SqlDataReader '------------------------------------------------------------ ' データベースコネクション作成 '------------------------------------------------------------ '------------------------------------------------------------ ' データベースのオープン '------------------------------------------------------------ Try objConnect.Open() objReadConnect.Open() Catch ex As SqlClient.SqlException pclsLog.P_ILPut(0, "DeleteRecordMain", "E", MSE001 + ex.Message) Return False End Try 先ほどの処理を呼ぶサブルーチン '------------------------------------------------------------ ' クローズ '------------------------------------------------------------ ' データベースクローズ objConnect.Close() objReadConnect.Close() | ||||
|
投稿日時: 2004-02-04 15:44
プログラム上のミスの指摘
せっかくtry〜catchしていますが、例外が発生したとき、コネクションを閉じる処理が通らないところにあります。 IDisposableインタフェースを実装するクラスは、ガベージコレクタが管理しないリソースを使います。したがって、開発者が「これ、もう要らない」と思った時点で必ずDisposeメソッドをコールしなければなりません。 修正例: Try objConnect.Open() objReadConnect.Open() 先ほどの処理を呼ぶサブルーチン Catch ex As SqlClient.SqlException pclsLog.P_ILPut(0, "DeleteRecordMain", "E", MSE001 + ex.Message) Return False Catch ex As Exception ' これはログしなくていいの? Return False Finally objConnect.Close() objReadConnect.Close() End Try じゃぁ、なんでConnectionはCloseで、Disposeではないか。それはマニュアルに「Closeを呼べ」と書いてあるからです^^;。 | ||||
|
投稿日時: 2004-02-04 16:06
トランザクションを使用しては如何でしょうか?
使用例:
| ||||
|
投稿日時: 2004-02-04 16:28
ソースミスのご指摘ありがとうございます。
>objConnectをクローズしてからDataReaderを取得したらどうなります? うまくSELECT文を発行してくれましたが,DBをクローズしてしまったので その後の処理のINSERT文で失敗です。 どうやって回避すればよろしいでしょうか? また,トランザクションに関してですが, 下記の様にやっております。すいません。部分,部分で。 ちなみに, '------------------------------------------------------------ ' データベースコネクション作成 '------------------------------------------------------------ objConnect = New SqlClient.SqlConnection(ConnectionString_INV) objReadConnect = New SqlClient.SqlConnection(ConnectionString_INV) '------------------------------------------------------------ ' データベースのオープン '------------------------------------------------------------ Try objConnect.Open() objReadConnect.Open() Catch ex As SqlClient.SqlException pclsLog.P_ILPut(0, "DeleteRecordMain", "E", MSE001 + ex.Message) Return False End Try '------------------------------------------------------------ ' データ読込みコマンド作成 '------------------------------------------------------------ ' 削除用 objSQLCommand = objConnect.CreateCommand objSQLCommand.Connection = objConnect ' 読込用 objSQLReadCommand = objReadConnect.CreateCommand objSQLReadCommand.Connection = objReadConnect ' トランザクション開始 Try objTran = objConnect.BeginTransaction(IsolationLevel.Serializable) objSQLCommand.Transaction = objTran Catch ex As SqlClient.SqlException pclsLog.P_ILPut(0, "DeleteRecordMain", "E", "トランザクションの開始に失敗しました。" + ex.Message) Return False End Try '------------------------------------------------------------ ' 機器ID変更データ出力処理 '------------------------------------------------------------ If strIDERRFLG = "1" Then bRet = KikiIdChange(objSQLReader, objSQLReadCommand, objReadConnect, objSQLCommand) End If If bRet = True Then サブルーチンを呼ぶ End If '------------------------------------------------------------ ' コミット/ロールバック '------------------------------------------------------------ If bRet = True Then Try ' コミット処理 objTran.Commit() Catch ex As SqlClient.SqlException bRet = False pclsLog.P_ILPut(0, "DeleteRecordMain", "E", "コミットに失敗しました。" + ex.Message) End Try End If If bRet = False Then ' ロールバック処理 objTran.Rollback() End If '------------------------------------------------------------ ' クローズ '------------------------------------------------------------ ' データベースクローズ objConnect.Close() objReadConnect.Close() |