TransWikia.com

テキストファイルを元に OracleDB へ登録するバッチの良い作り方を教えてください

スタック・オーバーフロー Asked on November 5, 2021

テキストファイル(id,value)の読み込み → パース → DB(Oracle) にInsert (重複idの時は、 Updateでvalue加算)
という処理のバッチを作るのですが、効率的な処理の方法を教えてください。
1回の処理件数 → 1万件は超えないものと想定

想定している手順

  • テキストファイル(id,valueが書かれている)読み込み
  • 読み込みループの中、SQL文字列を作っていく
  • Merge?
  • Update or Insert?

という処理を考えています。
以下のSQLふぐあいをおこします。

MERGE INTO USERS
USING DUAL
ON (id='001')
WHEN MATCHED THEN
    UPDATE SET no='002' ,from_date = TO_DATE('20-07-01 00:00:00', 'YY-MM-DD HH24:MI:SS')
WHEN NOT MATCHED THEN
INSERT USERS (id,no,from_date) VALUES ('02','t002',TO_DATE('20-07-01 00:00:00', 'YY-MM-DD HH24:MI:SS'));

One Answer

javaからテキストファイルを読み込み、JDBCを呼び出す一連の流れはできる前提で回答します。

難しく考えずにトランザクションを増やさなければ効率的な処理をすることができます。
高々1万件ならば、1回のトランザクションがDBに負荷を掛け過ぎるリスクは無視できるでしょう。

OK: つまりこの疑似コードは効率的です。(try-catch-finallyやrollbackは省略)

// 最初にコネクションを作成してオートコミットしない
Connection conn = DriverManager.getConnection();
conn.setAutoCommit(false); 

BufferedReader br = new BufferedReader(new FileReader(new File(hoge)));
String line = br.readLine();
while(line != null) {
    String sql = myParser(line);  //独自のパーサでmerge文を作る
    Statement statement = conn.createStatement();
    statement.executeUpdate(sql);
    statement.close();
    line = br.readLine();
}
conn.commit();  //最後にトランザクションが終了
conn.close();

NG: この疑似コードは効率的ではありません。

BufferedReader br = new BufferedReader(new FileReader(new File(hoge)));
String line = br.readLine();
while(line != null) {
    String sql = myParser(line);  //独自のパーサでmerge文を作る
    // 1行ごとにトランザクションを作って自動コミットする
    Connection conn = DriverManager.getConnection();
    Statement statement = conn.createStatement();
    statement.close();
    conn.close();
    statement.executeUpdate(sql);
    line = br.readLine();
}

insert all: 効率的なデータ処理を求めるならばinsert allの使用も検討すると良いでしょう。

insert all
into hoge values(1, 'fuga')
into hoge values(2, 'piyo')
select * from dual; -- 最後のselect文は省略不可

merge?: insert/updateとmerge文のどちらを使うべきかについては、毎回sql作成時にselectしてinsert文とupdate文の条件分岐をするよりもmerge文の方が効率的です。


編集後のSQLはORA-00926: missing VALUES keywordエラーが発生しています。
※最新の編集でSQL文が消えていたのでロールバックしました。

エラーの原因はWHEN NOT MATCHED THEN以下のINSERTにUSERSテーブル名が書かれていることです。
Merge文ではテーブル名を省略します。

INSERTの行を下記のように書き直してみてください。

修正前: INSERT USERS (id,no,from_date) VALUES ('02','t002',TO_DATE('20-07-01 00:00:00', 'YY-MM-DD HH24:MI:SS'));
修正後: INSERT (id,no,from_date) VALUES ('02','t002',TO_DATE('20-07-01 00:00:00', 'YY-MM-DD HH24:MI:SS'));

SQL Fiddle

Answered by payaneco on November 5, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP