スタック・オーバーフロー Asked on November 5, 2021
テキストファイル(id,value)の読み込み → パース → DB(Oracle) にInsert (重複idの時は、 Updateでvalue加算)
という処理のバッチを作るのですが、効率的な処理の方法を教えてください。
1回の処理件数 → 1万件は超えないものと想定
想定している手順
という処理を考えています。
以下の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'));
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'));
Answered by payaneco on November 5, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP