- PR -

ado.net ループ時のinsertについて

投稿者投稿内容
いっく☆
常連さん
会議室デビュー日: 2003/11/26
投稿数: 35
投稿日時: 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()


一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2004-02-04 13:20
投げられたExceptionのMessageはどうなってますか?
それが解決のヒントになるかと。

あと、色々な識別子が出てきていますが、型がよくわかりません。
ソースの一部分をそのままコピペしただけのようですけど。

いっく☆
常連さん
会議室デビュー日: 2003/11/26
投稿数: 35
投稿日時: 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
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2004-02-04 13:57
objSQLCommandはコネクションとしてobjConnectを、
objSQLReadCommandはコネクションとしてobjReadConnectを使っているということですね?
(objConnectはソースには出てきませんが)

objConnectをクローズしてからDataReaderを取得したらどうなります?
いっく☆
常連さん
会議室デビュー日: 2003/11/26
投稿数: 35
投稿日時: 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()
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 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を呼べ」と書いてあるからです^^;。
つぢ
会議室デビュー日: 2003/10/29
投稿数: 9
投稿日時: 2004-02-04 16:06
トランザクションを使用しては如何でしょうか?

使用例:
コード:
Dim objTrans As SqlClient.SqlTransaction = objConnect.BeginTransaction()
objSQLCommand.Transaction = objTrans

INSERTロジック

objTrans.Commit()


いっく☆
常連さん
会議室デビュー日: 2003/11/26
投稿数: 35
投稿日時: 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()


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