TimberLandChapel 様。
お忙しい所、レスありがとうございます。
実行環境ですが、
VBSにて以下のものをループさせています。
簡単に書きますと、
①DB接続
↓
②トランザクション開始
↓
③あるフォルダの中にあるCSVファイルの数を取得し、その数だけループ
↓
④ 更にCSVファイルを読み込み、CSVファイルの行数分ループ
↓
⑤ 「TEST」TBLにCSVと同じ内容のデータがあれば、更新、なければ挿入
↓
⑥正常に処理が行われていれば、④、または③へ戻ってひきつづき処理を行う
↓ エラーが発生していた場合はここでROLLBACK
⑦ 全てのループから抜けたらここでCommit、DB接続解除
といった感じです。
以下、実際のソースを載せました。
見にくかったらすみません(--;)
また、補足ですが、更にその後パフォーマンスモニタにて、色々試してみたところ、
この処理を流した場合、以下のカウンタに変化が見られました。
・SQLSever:Databasesオブジェクト
LogCache Reads/Secカウンタ →平常時(0)から処理が落ちた時に一時的に100まで跳ね上がった
・SQLSever:Locksオブジェクト
Lock Requests/Secカウンタ →処理を流したと同時に100まで跳ね上がり、処理が落ちたと同時に40~45(平常時)まで戻った
・SQLSever:Memory Managerオブジェクト
Lock Blocksカウンタ →処理を流してしばらくしてから一定間隔であがりつづけ、80くらいに達して落ちたと同時に平常時(50)まで戻った
Lock Ownerカウンタ →処理を流してしばらくしてから一定間隔であがりつづけ、80くらいに達して落ちたと同時に平常時(50)まで戻った
この中で、特にSQLSever:Memory ManagerオブジェクトのLock
BlocksとLock Ownerが原因に絡んでいるのではないかと思っているのですが、
ロックブロックが何かよくわからずに先に進めずにおります。
ちなみに、以前プロファイラにて、Event Classのロックに関する項目にチェックを入れて処理を流してみたところ、ロックに関する文字はありませんでしたので、
ABENDの原因はロックではないと思っていたのですが、このロックとロックブロックとは別のものなのでしょうか?
そして、パフォーマンスモニタのロックブロックの値が一定間隔であがっていることからしてやはりロックが原因で落ちているのでしょうか・・?
また、ABEND時のロックブロックの詳細をみるにはどうしたらよいのでしょうか・・?
わからないことだらけです(TT)
Sub main()
'=======================================================================
' 準備
'=======================================================================
Dim dsn
Dim rcd
'** DSN 設定
dsn = "接続情報"
'** ODBC 接続
On Error Resume Next
Set s3cn_ado = CreateObject("ADODB.Connection")
s3cn_ado.Open dsn
s3cn_ado.CursorLocation = 3
rcd = Err.number
If rcd <> 0 Then
MsgBox "データベースに接続出来ません。"
Exit Sub
else
msgbox "接続"
End If
Call EXECUTE
Call DB_CLOSE
End Sub
'=======================================================================
' 後始末
'=======================================================================
Private Sub DB_CLOSE()
'** ODBC 接続解除
On Error Resume Next
s3cn_ado.Close
'On Error GoTo 0
End Sub
'=======================================================================
' メイン
'=======================================================================
Private Sub EXECUTE()
'** RDB 処理
If RdbShori() = False Then
s3cn_ado.RollbackTrans
'errmsg = "Description=" & objErrItem.Description & "Number=" &
objErrItem.Number
Call fncLogPut (Msg, gstrPath & "log.txt")
MsgBox Msg & "RDB 更新に失敗しました。"
Else
Call fncLogPut (Msg, gstrPath & "log.txt")
MsgBox "RDB 更新正常終了。"
End If
End Sub
'=======================================================================
' RDB 処理
'=======================================================================
Function RdbShori()
Dim strPath
Dim strflpt 'OPENファイルNAME保持用変数
Dim strData
Dim strLen
Dim strStr1, strStr2
Dim Filenames
Dim i
Dim objErrItem
Dim rstWork
dim myFSO
Dim myfile
Dim f1
Dim fc
Dim myFolder
Dim p
'** エラーセット
RdbShori = False
'** トランザクション開始
s3cn_ado.BeginTrans
'** エラートラップ開始
On Error Resume Next
SET rstwork = createobject("adodb.recordset")
set myFso = CreateObject("Scripting.FileSystemObject")
'フォルダ内のファイル数を取得し、その数だけループ
Set myFolder = myFso.GetFolder(gstrPath)
Set fc = myFolder.Files
For Each f1 in fc
Filenames = f1.name
If Filenames = "" Then
MsgBox "このフォルダには.csvブックは存在しません。"
Exit Function
ElseIF RIGHT(Filenames,3) = "csv" Then
strPath = gstrPath & Filenames
set myfile = myFso.OpenTextFile(strPath, 1,true)
blnFileFlg = True
II = 0
p = 1
Do While Not myfile.AtENDOFSTRG ' ファイルの終端までループを繰り返す
mytxt = myfile.ReadLine
For I = 0 TO 9
strHBuf(i) = Left(mytxt,Instr(mytxt,",") - 1)
mytxt = Mid(mytxt,Instr(mytxt,",") + 1)
If Instr(mytxt,",") = 0 then
Exit For
End IF
Next
strHbuf(9) = mytxt
Erase strRow
strRow(0) = strHBuf(0)
strRow(1) = strHBuf(1)
strRow(2) = strHBuf(2)
strRow(3) = strHBuf(3)
strRow(4) = strHBuf(4)
strRow(5) = strHBuf(5)
strRow(6) = strHBuf(6)
strRow(7) = FormatDateTime(Now, 0)
strRow(8) = FormatDateTime(Now, 0)
strRow(9) = strHBuf(9)
'**データ型,桁数を調べる
'**TESTTBLのレコード存在チェック
strSql = ""
strSql = "SELECT * "
strSql = strSql & "FROM TEST "
strSql = strSql & "WHERE TEST.A = '" & strRow(0) & "'"
strSql = strSql & " AND FRIM(TEST.B) = '" & strRow(1) & "'"
strSql = strSql & " AND TEST.C = '" & strRow(2) & "'"
rstWork.Open strSql, s3cn_ado, 3,1
If rstWork.EOF Then
'** TESTにデータがなければ挿入、あれば更新
strSql = ""
strSql = "INSEF INTO TEST Values "
strSql = strSql & "( '" & strRow(0) & "', "
strSql = strSql & "'" & strRow(1) & "', "
strSql = strSql & "'" & strRow(2) & "', "
strSql = strSql & strRow(3) & ", "
strSql = strSql & strRow(4) & ", "
strSql = strSql & strRow(5) & ", "
strSql = strSql & strRow(6) & ", "
strSql = strSql & "'" & CDate(strRow(7)) & "', "
strSql = strSql & "'" & CDate(strRow(8)) & "', "
strSql = strSql & "'" & strRow(9) & "')"
Else
strSql = ""
'strSql = "SET STATISTICS
PROFILE ON"
strSql = strSql & "UPDATE TEST "
'strSql = strSql & "SET A = '" & strRow(0) & "', "
'strSql = strSql & "B = '" & strRow(1) & "' , "
'strSql = strSql & "C = '" & strRow(2) & "', "
strSql = strSql & "SET D = " & strRow(3) & ", "
strSql = strSql & "E = " & strRow(4) & ", "
strSql = strSql & "F = " & strRow(5) & ", "
strSql = strSql & "G = " & strRow(6) & ", "
'strSql = strSql & "H = '" & CDate(strRow(7)) & "', "
strSql = strSql & "I = '" & CDate(strRow(8)) & "', "
strSql = strSql & "J = '" & strRow(9) & "' "
strSql = strSql & " WHERE TEST.A = '" & strRow(0) & "'"
strSql = strSql & " AND TEST.B = '" & strRow(1) & "'"
strSql = strSql & " AND TEST.C = '" & strRow(2) & "'"
'strSql = strSql & ":: fn_trace_getinfo(default)"
End If
s3cn_ado.Execute (strSql)
'**エラーナンバーが0以外だったらロールバックして終了
If Err.Number <> 0 Then
s3cn_ado.RollbackTrans
Set objErrItem = s3cn_ado.Errors.Item(0)
errmsg = "Description=" & objErrItem.Description &
"Number=" & objErrItem.Number
Call fncLogPut (errmsg, gstrPath & "log.txt")
Exit Function
End If
rstWork.Close
P = P + 1
Loop
Msg = Msg & vbCrLf & Filenames & "の処理完了。"
'**csvファイルを閉じる
myfile.Close
end if
Next
'** エラートラップ終了
'** トランザクション終了
s3cn_ado.CommitTrans
'** 正常セット
RdbShori = True
End Function
'**********************************************************************
'**********************************************************************
Function fncLogPut(ByVal strLog, ByVal strFlNm)
Dim objFso
Dim objLog
Dim strFilePath
strFilePath = strFlNm
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objLog = objFso.OpenTextFile(strFilePath, 8, True)
objLog.WriteLine (strLog )
objLog.Close
Set objLog = Nothing
Set objFso = Nothing
End Function
Post by TimberLandChapelPost by keikon97あるクエリをループにて何回も流す処理を行っています。
回数が少ない分には問題ないのですが、流す回数が多いとクエリタイムアウト(30秒)にて
落ちてしまいます。
--
お疲れ様です。
TimberLandChapel です。
クエリをループさせているプラットフォームは何でしょう?
T-SQL で WHILE 文を使用していますか?
VB6.0 などから ADO の処理をループさせていますか?
VB.NET などから ADO.NET の処理をループさせていますか?
クエリタイムアウトということなので,プログラムからのアクセスだと予想はできますが。
また,
クエリを発行しているテーブルの情報と,
クエリの詳細を開示いただけますか?
「ロックがかかっていない」というところから,参照系の処理だと予想はできますが,
正確にはロック待ちが発生していないということだと思います。
どういった構成のテーブルにどんなクエリを発行しているのかがわかれば検討できると思います。
プロファイラでのイベントクラスの意味については,
TSQL イベントクラスを Books Online で見ていただければわかると思います。
また,一般的な SQL Server のクエリタイムアウトの情報は
query wait オプションを参照ください。
(これは基本的には大量にメモリを消費するハッシュ演算などでのお話になります)
よろしくお願いいたします。
----------
TimberLandChapel
http://blogs.timberlandchapel.com/blogs/workshop/archive/2006/02/04/649.aspx