はじめに
お世話になっております。
今回は大量のデータベースをCSV化することについて質問いたします。
OracleデータベースをVB6でCSV化する必要がありました。
(OracleをPostgreに移行したいけど、方法がCSVをpsqlで読み込むしか考えつかなかったため)
ので、ササっと以下のように作りました。
VB6
1 'データ出力 2 strSQL = "" 3 strSQL = strSQL & "SELECT * " 4 strSQL = strSQL & "FROM " & strSchema & "." & strTable & " " 5 6 Set objData = Po_DataBase.DbCreateDynaset(strSQL, ORADYN_DEFAULT) 7 8 'ファイルオープン 9 Set FSO = CreateObject("Scripting.FileSystemObject") 10 Set Ts = FSO.OpenTextFile(strOutput & strTable & "_" & Format(DateTime.Date, "yyyyMMdd") & ".csv", ForWriting, True) 11 12 'ファイル出力 13 With Ts 14 Dim i As Integer 15 Dim j As Integer 16 objData.MoveFirst 17 Do While objData.EOF = False 18 strOut = "" 19 For j = 0 To intFldCount 20 strOut = strOut & CORA20_FieldsValue(objData, objDataFld, j) & "," 21 Next 22 23 strOut = Left(strOut, Len(strOut) - 1) 24 25 .WriteLine strOut 26 27 'ここでエラーが発生 28 objData.movenext 29 Loop 30 End With
何がダメだったか
一応上記のプログラムは動きました。
ある程度のデータ数ならCSVとして吐き出すことができます。
しかし、出力データ数が226,482KBを超えたところでエラーが発生して、
途中のデータまでしかCSV化できませんでした。
要望
今回は半分うまくいっているので、言語や手法を変えずにできる方法を探しています。
よろしければご教授願います。
追記1
エラー箇所にErr.Descriptionを仕込んでみたら
「メモリ不足です」と表示されました。
この場合、メモリを増築するなどで対処できますでしょうか?
もしくは、SQL部分をチューニングしたり、分割出力(やり方はわからないです)などで回避できるものでしょうか?
追記2
エラーの発生個所は、上記コードに追記しています。
FieldValueは以下のようになっています。
VB6
1Public Function CORA20_FieldsValue(ByRef Ho_DBObject As Object _ 2 , Ho_Fields() As Object _ 3 , Hn_Idx As Integer) As String 4 5 Dim Ls_Ret As String 6 7 On Error GoTo CORA20_FieldsValue_ERR 8 9 '/* 戻り値クリア 10 If Not Ho_Fields(Hn_Idx) Is Nothing Then 11 If Pb_ADO_ConnectFlg = True Then 12 Ls_Ret = CStr(IIf(Ho_Fields(Hn_Idx).Type = 202, vbNullString, 0)) 13 Else 14 Ls_Ret = CStr(IIf(Ho_Fields(Hn_Idx).OraIDataType = 1, vbNullString, 0)) 15 End If 16 Else 17 Ls_Ret = vbNullString 18 End If 19 20 'Null値が存在する場合は必ず IsNullを使用する。 21 If Not IsNull(Ho_Fields(Hn_Idx).Value) Then 22 If Pb_ADO_ConnectFlg = True Then '/* ADO 23 Dim Ls_Value As String 24 Ls_Value = CStr(Ho_Fields(Hn_Idx).Value) 25 If Len(Trim(Ls_Value)) = 0 Then 26 Ls_Value = vbNullString 27 End If 28 Ls_Ret = Ls_Value 29 Else 30 Ls_Ret = CStr(Ho_Fields(Hn_Idx).Value) 31 End If 32 Else 33 If Pb_ADO_ConnectFlg = True Then '/* ADO 34 Ls_Ret = IIf(Ho_Fields(Hn_Idx).Type = 202, vbNullString, 0) 35 36 Else '/* Oracle Object for OLE 37 Ls_Ret = IIf(Ho_Fields(Hn_Idx).OraIDataType = 1, vbNullString, 0) 38 End If 39 End If 40 41 CORA20_FieldsValue = Ls_Ret 42 43 Exit Function 44 45CORA20_FieldsValue_ERR: 46 If Err.Number <> 0 And Err.Number <> 3021 Then 47 Call CORA20_ORAErr(Po_DataBase, "CORA20_FieldsValue") 48 Call CMSG00_ORAErr("CORA20_FieldsValue") 49 End If 50 51 CORA20_FieldsValue = Ls_Ret 52End Function
接続コードは以下のようになっています。
VB6
1Function CORA00_DB_Connect(ByRef Ho_DBObject As Object _ 2 , ByVal Hs_DatabaseName As String _ 3 , ByVal Hs_UserName As String _ 4 , ByVal Hs_Password As String) As Integer 5 6 Dim Ls_Connect As String 7 8 'VBのエラーとして判断するためエラー処理を行う。 9 On Error GoTo CORA00_DB_Connect_Err 10 11 CORA00_DB_Connect = Ret_NG 12 13 '/* 接続形態チェック 14 Pb_ADO_ConnectFlg = CheckAdoConnection 15 16 If Pb_ADO_ConnectFlg = True Then '/* ADO 17 Set Ho_DBObject = New clsADO 18 19 'ここを通っている 20 Ls_Connect = "Provider=OraOLEDB.Oracle; Data Source=" & Hs_DatabaseName & ";" _ 21 & "User Id=" & Hs_UserName & ";" _ 22 & "Password=" & Hs_Password & ";" 23 '/* クライアントカーソル使用 24 Ho_DBObject.CursorLocation = adUseClient 25 26 '/* 接続文字列セット 27 Ho_DBObject.ConnectionString = Ls_Connect 28 29 '/* DB接続 30 Ho_DBObject.ConnectDatabase Ho_DBObject.ConnectionString, Hs_UserName, Hs_Password 31 Else '/* Oracle Object for OLE 32 33 Ls_Connect = Trim$(Hs_UserName) & "/" & Hs_Password 34 35 'Lo_OraSessionオブジェクトは、アプリケーション内で使われる 36 'OraDatabaseおよびOraConnection、OraDynasetオブジェクト 37 'の集合を管理します。 38 'OralceをObjectとして認識します。 39 Dim Lo_OraSession As Object 40 Set Lo_OraSession = CreateObject("OracleInProcServer.XOraSession") 41 42 Set Ho_DBObject = Lo_OraSession.OpenDatabase(Hs_DatabaseName$, Ls_Connect$, ORADB_DEFAULT) 43 End If 44 45 CORA00_DB_Connect = Ret_OK 46 47 Exit Function 48 49CORA00_DB_Connect_Err: 50 51 Call CORA20_ORAErr(Po_DataBase, "ORA000_DB_Connect") 52 Call CMSG00_ORAErr("ORA000_DB_Connect") 53 54End Function
追記3
YAmaGNZさんの案を採用させていただきました。
データを1~10000行、10001~20000行…という感じに分割して出力する方法に変更しようと思います。
早速ROWNUMを試しましたが、以下のようになってしまいます。



回答3件
あなたの回答
tips
プレビュー