
タブ区切りのtsvファイルの1項目目に並んでいるデータをDBのプライマリーキーとみなして、DB上に既にあればupdate、なければinsertします。
下のPGは、DBに30万件のデータが入った状態で実行すると、遅すぎて使えません。もっと速くすることはできませんでしょうか。
Public Const OraSQL_01 = "INSERT INTO CUSTOMER (COMPANY_CODE, TEST1) Values (:データ0, :データ1)"
Public Const OraSQL_02 = "UPDATE CUSTOMER SET COMPANY_CODE = :データ0, TEST1 = :データ1 WHERE COMPANY_CODE = :データ0"
wkFile1 = "c:\test\test.csv"
Open wkFile1 For Input As #1
OraSession.BeginTrans
Set rs = OraDatabase.CreateDynaset("SELECT COMPANY_CODE FROM CUSTOMER", ORADYN_DEFAULT)
OraDatabase.Parameters.Add "データ0", 0, ORAPARM_INPUT
OraDatabase.Parameters("データ0").ServerType = ORATYPE_NUMBER
OraDatabase.Parameters.Add "データ1", 0, ORAPARM_INPUT
OraDatabase.Parameters("データ1").ServerType = ORATYPE_VARCHAR2
Do Until EOF(1)
Line Input #1, Text
sec = Split(Text, vbTab)
OraDatabase.Parameters("データ0").Value = sec(0)
OraDatabase.Parameters("データ1").Value = sec(1)
Dim flg As Boolean
Do Until rs.EOF
flg = False
If rs("COMPANY_CODE") = sec(0) Then
OraDatabase.ExecuteSQL OraSQL_02
flg = True
Exit Do
Else
rs.MoveNext
End If
Loop
If flg = False Then
OraDatabase.ExecuteSQL OraSQL_01
End If
rs.MoveFirst
Loop
OraSession.CommitTrans
No.1ベストアンサー
- 回答日時:
ざっと眺めただけだが確かに遅すぎて使えそうにないな。
アプローチ1.tsvから1行読み込んだら、1列目(顧客コード)をキーにselectして引っかかればupdate、引っかからなければinsertを実行するように変更する。
これはあれなのかな? ひょっとしたらtsvに同じ顧客コードが2行以上あった時に、毎回selectするとエラーが発生せずに1回目に出てきたの餡餅商事はinsert→2回目以降に出てきた餡餅商事はupdateでエラーが発生せずに終わってしまうからダメなのかな? それならこのアプローチを取らなかった理由は分かる。
アプローチ2.顧客コード一覧をダイナセットで取る時に顧客コードを昇順でソートし、バイナリサーチを使うように変更する。
これは説明の必要もないだろう。シーケンシャルサーチはありえんだろう。30万行やし。
この回答への補足
anmochiさんご回答有難うございます。
恐縮ですが、アプローチ1をとる場合の書き方がわかりません。
1列目をキーにSELECTしてダイナセットで取るには
Set rs = OraDatabase.CreateDynaset("SELECT COMPANY_CODE FROM CUSTOMER WHERE COMPANY_CODE = :データ0", ORADYN_DEFAULT)
でよいかと思いますが、ひっかかっる、ひっかからないのコードはどのように記述すれば宜しいのでしょうか、わかれば教えて頂けませんでしょうか。
宜しくお願いします。
コードの記述方法がわかりました。
Set rs = OraDatabase.CreateDynaset("SELECT COMPANY_CODE FROM CUSTOMER WHERE COMPANY_CODE = :データ0", ORADYN_DEFAULT)
If rs("COMPANY_CODE") = sec2(0) Then
OraDatabase.ExecuteSQL OraSQL_02
Else
OraDatabase.ExecuteSQL OraSQL_01
End If
でできました。
有難うございました。
No.4
- 回答日時:
こんな手も。
1.空のテンポラリの表を作成。主キーもつけておく。
2.テキストファイルの内容をテンポラリ表にSQL*Loaderでロード
3.更新対象のデータをCUSTOMERから削除
delete from CUSTOMER where COMPANY_CODE in (select COMPANY_CODE from テンポラリ表);
4.テンポラリ表の内容をCUSTOMERに追加
insert into CUSTOMER select * from テンポラリ表;
5.テンポラリ表の削除。
#CUSTOMERテーブルの行数だけではなく、テキストファイルの行数も多ければ、下手にロジック組むよりこの方が高速です。
No.2
- 回答日時:
selectというか、Dynaset不要。
insertして一意制約違反だったらupdateすればいいだけ。updateの際は、主キーの項目はsetに含めない。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
【ExcelVBA】5万行以上のデー...
-
VBAでCOPYを繰り返すと、処理が...
-
【マクロ】並び替えの範囲が、...
-
vbsでのwebフォームへの入力制限?
-
VBAの「To」という語句について
-
算術演算子「¥」の意味について
-
【ExcelVBA】値を変更しながら...
-
【マクロ】開いているブックの...
-
Vba セルの4辺について罫線が有...
-
【マクロ】シートの変数へ入れ...
-
エクセルのマクロについて教え...
-
エクセルのVBAコードと数式につ...
-
ワードの図形にマクロを登録で...
-
Vba FileSystemObject オブジェ...
-
ダブルクリックで貼り付けた画...
-
エクセルVBA 段落番号自動取得方法
-
エクセルのマクロについて教え...
-
VBAでユーザーフォームを指定回...
-
Excel VBA 選択範囲の罫線色の...
-
vbaにてseleniumを使用したedge...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
時間の判定条件
-
SQLについて
-
ActiveReports
-
accessvbaで内容を結合して保存
-
VBA 条件に合わせたデータ抽出
-
指定文字を太字にするVBAを別シ...
-
配列への分割方法
-
複数のデータテーブルのデータ...
-
SQLローダーCSV取込で、囲み文...
-
テーブルの最後(最新)のレコー...
-
単一グループのグループ関数で...
-
Oracleで「文字が無効です」の...
-
SELECT FOR UPDATE で該当レコ...
-
【PL/SQL】FROM区に変数を使う方法
-
レコードの登録順がおかしい
-
select文の実行結果に空白行を...
-
where句中のtrim関数について
-
count関数の値をwhere句で使用...
-
データ
-
SQL*Loader Append
おすすめ情報