質問です。というか、教えてください。
sesOra.BeginTrans
Do While Not EOF(intFno)
Line Input #intFno, strBuf
'1行分のデータを設定する
strData = ""
Do While InStr(strBuf, ",") > 0
strData = strData & "'" & strQuote(Trim$(Left$(strBuf, InStr(strBuf, ",") - 1))) & "',"
strBuf = Mid$(strBuf, InStr(strBuf, ",") + 1)
DoEvents
Loop
strData = strData & "'" & strQuote(Trim$(strBuf)) & "'"
lngRet = dbOra.DbExecuteSQL(strSQL & " (" & strData & ")")
'DoEvents
Loop
sesOra.CommitTrans
↑をバインド配列を使用したものに変換したいんですけど、
うまくできません。
誰か教えてください。
よろしくお願いします。
自己レスです。
ちなみにoo4oでやってます。
どなたかアドバイスお願いします。
# 回答が付かないようなので。
バインド配列のコードに関しては、ヘルプに具体例があるはずです。
oo4oのヘルプで、OraParamArrayについて調べてください。
ところで、現在の strSQL の中身はどうなっているのでしょうか?
SQLの内容によっては、バインド配列化できない事もありえますので…。
返事ありがとうございます。
下に載せるソースはCSVファイルのインポートをするものですが、
あまりに処理が遅いためバインド配列を利用しようと考えました。
バインド配列に関しては自分なりに調べました。
配列のサンプルになると、どれもFor文になってしまうし、
EOFの場合では、どのようなソースにしてよいのかわからないので
質問させていただきました。
Public Function ImportData(ByVal vstrFilename As String) As Boolean
Dim strSQL As String 'SQL文
Dim blnRet As Boolean
Dim lngRet As Long
Dim intFno As Integer
Dim strData As String '項目値
Dim strBuf As String '読み込みバッファ
Dim strErrText As String
On Error GoTo errInsertData:
blnRet = False
intFno = FreeFile
Open vstrFilename For Input Access Read Lock Read Write As #intFno
'定義体のフィールド取得
Line Input #intFno, strBuf
sesOra.BeginTrans
Do While InStr(strBuf, ",") > 0
strSQL = strSQL & Trim$(Left$(strBuf, InStr(strBuf, ",") - 1)) & ","
strBuf = Mid$(strBuf, InStr(strBuf, ",") + 1)
DoEvents
Loop
sesOra.CommitTrans
strSQL = "INSERT INTO ITEM (" & _
strSQL & Trim$(strBuf) & _
") VALUES"
'テーブルにデータをINSERTする
sesOra.BeginTrans
Do While Not EOF(intFno)
Line Input #intFno, strBuf
'1行分のデータを設定する
strData = ""
Do While InStr(strBuf, ",") > 0
strData = strData & "'" & strQuote(Trim$(Left$(strBuf, InStr(strBuf, ",") - 1))) & "',"
strBuf = Mid$(strBuf, InStr(strBuf, ",") + 1)
DoEvents
Loop
strData = strData & "'" & strQuote(Trim$(strBuf)) & "'"
lngRet = dbOra.DbExecuteSQL(strSQL & " (" & strData & ")")
'DoEvents
Loop
sesOra.CommitTrans
blnRet = True
exitInsertData:
On Error Resume Next
Close #intFno
' lblInsert.Caption = "設定完了"
ImportData = blnRet
Exit Function
errInsertData:
If sesOra.LastServerErr = 0 Then
If dbOra.LastServerErr = 0 Then
strErrText = Error$
Else
strErrText = dbOra.LastServerErrText
dbOra.LastServerErrReset
End If
Else
strErrText = sesOra.LastServerErrText
sesOra.LastServerErrReset
End If
MsgBox strErrText, vbOKOnly + vbExclamation, "Error"
Resume exitInsertData:
Resume Next
End Function
Private Function strQuote(ByVal vstrItem As String) As String
Dim strWork As String
strWork = ""
Do While InStr(vstrItem, "'") > 0
strWork = strWork & Left$(vstrItem, InStr(vstrItem, "'") - 1) & "''"
vstrItem = Mid$(vstrItem, InStr(vstrItem, "'") + 1)
DoEvents
Loop
strQuote = strWork & vstrItem
End Function
このような場合のSQLでは配列化は可能でしょうか?
よろしくお願いします。
あら。知りたかったのは、「strSQL の中身」だけだったのですが……
現状のstrSQL の生成手順を示してくださったようですね。m(_ _)m
vstrFilename の内容がわからなかったので、最終的なstrSQLの中身が
どうなるのかわかりませんでしたが、おおよその類推はできました。現状は、
strSQL = "INSERT INTO ITEM (" & 列定義 & ") VALUES (" & 値定義 & ")"
のようなSQLを動的に作成し、それを ExecuteSQL している…という事ですよね。
> 配列のサンプルになると、どれもFor文になってしまうし、
For文でもDo文でも、ループである事には変わりありませんよね?
まず、バインド配列変数を定義するために、AddTableメソッドに
バインド変数名(例: "STAFF_NAME")
入出力方向(例: ORAPARM_INPUT)
データ型(例: ORATYPE_CHAR)
配列の行数
データ型のサイズ(数値または文字列の時のみ指定)
という5個(4個)のパラメータを指定して、各パラメータを定義します。
なお、配列の行数に関しては、元データの総件数を指定すればOKです。
# 元データの行数が多すぎぎる場合は、指定する件数を減らして、
# 何回かに分けて実行した方が良いかもしれません。適宜調整してください。
次に、put_Valueメソッドで、バインド配列に値を格納して行きます。
最後に、CreateSqlメソッドで
strSQL = "INSERT INTO STAFF_NAME (ID, STAFF_NAME, MAIL) VALUES (:ID, :STAFF_NAME, :MAIL)"
といった形式の SQL を実行してやればOKです。
(上記のSQLの場合、"ID", "STAFF_NAME", "MAIL" という3種のバインド変数が使われます)
レスありがとうございます。
>なお、配列の行数に関しては、元データの総件数を指定すればOKです。
とありますが、
データ件数がわからないのでEOFを使っています。
総件数を指定すればOKとありますが、総件数を調べるSQL文を発行して、
その値を指定すれば良いということでしょうか?
># 元データの行数が多すぎぎる場合は、指定する件数を減らして、
># 何回かに分けて実行した方が良いかもしれません。適宜調整してください。
ちなみに開発本番では3桁のデータ件数の予定ですが、
現状5桁のデータ件数で開発を進めています。
EOFで最終行をとっているとき、回数をわけて実行するには
どうのような方法でループを実行したらよいのでしょうか?
簡単な質問ばかりですみません。
よろしくお願いします。
自己レスです。
ちょっと勘違いして送ってしまいました。
>なお、配列の行数に関しては、元データの総件数を指定すればOKです。
とありますが、
データ件数がわからないのでEOFを使っています。
総件数を指定すればOKとありますが、総件数を調べるSQL文を発行して、
その値を指定すれば良いということでしょうか?
># 元データの行数が多すぎぎる場合は、指定する件数を減らして、
># 何回かに分けて実行した方が良いかもしれません。適宜調整してください。
ちなみに開発本番では3桁のデータ件数の予定ですが、
現状5桁のデータ件数で開発を進めています。
この場合、パラメータの配列数はとりあえず
100件ということでいいのでしょうか?
あと、EOFのときのループで回数をわけるときは
どのようなコーディングになるんでしょうか?
よろしくお願いします。
提示されたコードを見た限りは、元データはCSVファイルなのですよね?
であれば、ファイル終端に到達するまでに、Line Input #の実行回数を
数えば、総件数もわかりますよね。
> この場合、パラメータの配列数はとりあえず
> 100件ということでいいのでしょうか?
適切な配列数というのはケースバイケースです。
ネットワークの都合やユーザー数、DBの設定などに応じて、
適切な件数は変わります。実際に試して確認してください。
とりあえずは全て一括で送ってみて、それで問題があるようなら、
件数を減らしていくという方向で考えてみては如何でしょう。
返事遅くなりました。
テーブルの項目が9個あるんですけど、こんな感じ↓でいいんでしょうか?
とりあえずデータが1万件と仮定しています。
'バインド配列変数の作成
Dim Item_code_Array As OraParamArray
Dim Item_name_Array As OraParamArray
Dim Youryou_Array As OraParamArray
Dim Kana_name_Array As OraParamArray
Dim Sekitukesuu_Array As OraParamArray
Dim Irisuu_Array As OraParamArray
Dim Size_w_Array As OraParamArray
Dim Size_d_Array As OraParamArray
Dim Size_h_Array As OraParamArray
OraDatabase.Parameters.AddTable "Item_code_Array", ORAPARM_INPUT, ORATYPE_NUMBER, 10000, 14
OraDatabase.Parameters.AddTable "Item_name_Array", ORAPARM_INPUT, ORATYPE_VARCHR2, 10000, 40
OraDatabase.Parameters.AddTable "Youryou_Array", ORAPARM_INPUT, ORATYPE_VARCHAR2, 10000, 30
OraDatabase.Parameters.AddTable "kana_name_Array", ORAPARM_INPUT, ORATYPE_VARCHAR2, 10000, 40
OraDatabase.Parameters.AddTable "Sekitukesuu_Array", ORAPARM_INPUT, ORATYPE_NUMBER, 10000,9
OraDatabase.Parameters.AddTable "Irisuu_Array", ORAPARM_INPUT, ORATYPE_NUMBER, 10000, 4
OraDatabase.Parameters.AddTable "Size_w_Array", ORAPARM_INPUT, ORATYPE_NUMBER, 10000, 4
OraDatabase.Parameters.AddTable "Size_d_Array", ORAPARM_INPUT, ORATYPE_NUMBER, 10000, 4
OraDatabase.Parameters.AddTable "Size_h_Array", ORAPARM_INPUT, ORATYPE_NUMBER, 10000, 4
Set Item_code_Array = oraDb.Parameters("Item_code_Array")
Set Item_name_Array = oraDb.Parameters("Item_name_Array")
Set Youryou_Array = oraDb.Parameters("Youryou_Array")
Set Kana_name_Array = oraDb.Parameters("Kana_name_Array")
Set Sekitukesuu_Array = oraDb.Parameters("Sekitukesuu_Array")
Set Irisuu_Array = oraDb.Parameters("Irisuu_Array")
Set Size_w_Array = oraDb.Parameters("Size_w_Array")
Set Size_d_Array = oraDb.Parameters("Size_d_Array")
Set Size_h_Array = oraDb.Parameters("Size_h_Array")
よろしくお願いします。
ツイート | ![]() |