スケーラブルデータベースサーバ HiRDB Version 8 UAP開発ガイド

[目次][索引][前へ][次へ]

18.5.2 バッチ更新

JDBC2.1 コアAPIでは,Statementクラス及びPreparedStatementクラスにバッチ更新機能が追加されました。バッチ更新機能によって,複数のSQL,又は複数のパラメタ値を登録し,一括して実行できるようになります。

バッチ更新を実行する場合,HiRDBの配列を使用した機能が使用できます。

配列を使用した機能は,HiRDBに対して大量のデータを高速に更新したい場合に有効です。なお,配列を使用した機能については,「4.8 配列を使用した機能」を参照してください。

<この項の構成>
(1) Statementクラスでのバッチ更新
(2) PreparedStatementクラスでのバッチ更新
(3) CallableStatementクラスでのバッチ更新
(4) 注意事項

(1) Statementクラスでのバッチ更新

Statementクラスでのバッチ更新の留意点を次に示します。

なお,JDBCドライバでは,複数のSQLを一括実行できないため,登録されたSQLを逐次実行することになります。

(2) PreparedStatementクラスでのバッチ更新

PreparedStatementクラスでのバッチ更新の留意点を次に示します。

なお,JDBCドライバでは,次の場合に逐次実行します。

<注意事項>
2件目以降のaddBatchで,setXXXメソッドで指定するパラメタ数が不足していた場合,前回セットした値が引き継がれるため注意が必要です。
INTEGER型列が2列(列1,列2)ある場合の例を次に示します。
[指定例]
prepstmt.setInt(1,100);
prepstmt.setInt(2,100);
prepstmt.addBatch();
prepstmt.setInt(1,200);
prepstmt.addBatch();
prepstmt.executeBatch();
 
[説明]
  • 1件目のaddBatchで設定される値は,列1=100,列2=100となります。
    1件目のaddBatchでパラメタ数が不足している場合は,エラーが発生します。
  • 2件目のaddBatchで設定される値は,列1=200,列2=100となります。
    2件目のaddBatchで,列2の情報が更新されていないため,1件目のaddBatchの情報が引き継がれます。

(3) CallableStatementクラスでのバッチ更新

CallableStatementクラスでのバッチ更新の留意点を次に示します。

なお,JDBCドライバでは,複数行のストアドプロシジャの?パラメタを一括実行できないため,複数行のストアドプロシジャの?パラメタを逐次実行することになります。

注意事項:
結果セット(ResultSet)を返すストアドプロシジャは,バッチ更新ではストアドプロシジャを実行するまで結果セットを返すかどうか分からないため,ストアドプロシジャ内で更新をしている場合,更新が反映されることがあるので注意してください。例えば,更新後にその結果を検索し取得するストアドプロシジャを,バッチ更新で実行すると,BatchUpdateExceptionが発生するが,更新は反映されてしまうことがあります。

(4) 注意事項

(a) HiRDBサーバによる暗黙的コミット

SQL文のバッチ更新機能を使用する場合,addBatchしたSQL文に次のSQL文が含まれるとき,そのSQL文を実行した時点でHiRDBサーバが暗黙的にコミットするため,注意が必要です。

(b) パラメタとSQL文のaddBatchの混在時でのバッチ更新機能

パラメタとSQL文のaddBatchとの混在時は,一括更新をしないで逐次実行します。例を次に示します。

 
PreparedStatement pstmt = con.prepareStatement("UPDATE T1 SET C1=? WHERE C2=?");
pstmt.setInt(1, 1);
pstmt.setInt(2, 1);
pstmt.addBatch();
pstmt.setInt(1, 2);
pstmt.setInt(2, 2);
pstmt.addBatch();
pstmt.addBatch("INSERT INTO T2 VALUES(1,2,3)");
pstmt.setInt(1, 3);
pstmt.setInt(2, 4);
pstmt.addBatch();
pstmt.setInt(1, 4);
pstmt.setInt(2, 4);
pstmt.addBatch();
pstmt.executeBatch();
 

このUAPを実行すると,パラメタとSQL文のaddBatchが混在しているため,各addBatch単位でのSQL実行となります。そのため,次のUAPを実行した場合と同じ結果となります。

 
PreparedStatement pstmt = con.prepareStatement("UPDATE T1 SET C1=? WHERE C2=?");
pstmt.setInt(1, 1);
pstmt.setInt(2, 1);
pstmt.executeUpdate();
pstmt.setInt(1, 2);
pstmt.setInt(2, 2);
pstmt.executeUpdate();
pstmt.executeUpdate("INSERT INTO T2 VALUES(1,2,3)");
pstmt.setInt(1, 3);
pstmt.setInt(2, 4);
pstmt.executeUpdate();
pstmt.setInt(1, 4);
pstmt.setInt(2, 4);
pstmt.executeUpdate();
 

なお,パラメタとSQL文のaddBatchとが混在するバッチ更新機能を使用する場合,Connectionクラスの自動コミットモードを無効にすることを推奨します。

(c) HiRDBのBINARY型に対する?パラメタを含むSQL文でのバッチ更新

HiRDBのBINARY型に対する?パラメタを含むSQL文でバッチ更新をする場合,次の条件に該当するとき,一括更新をしないで逐次実行します。

(d) HiRDBのBLOB型に対する?パラメタを含むSQL文でのバッチ更新

HiRDBのBLOB型に対する?パラメタを含むSQL文でバッチ更新をする場合,一括更新をしないで逐次実行します。

(e) addBatchメソッドによって多数のパラメタを登録する場合

JDBCドライバは,addBatchメソッドで登録したすべてのパラメタを,executeBatchメソッドを実行するまでドライバ内に蓄積します。そのため,多数のパラメタを登録する際は,メモリ使用量に注意してください。

また,HiRDBの配列を使用した機能でバッチ更新をする場合,HiRDBサーバに対してJDBCドライバが要求できる実行回数は最大で30,000回です。30,001個以上のパラメタを登録している場合,1回のバッチ更新で用いるパラメタを30,000個単位に分割し,HiRDBサーバに対してSQLの実行を要求します。この場合も,JDBCドライバ内のメモリを消費するため,バッチ更新による性能向上効果が下がるおそれがあります。そのため,30,001回以上のSQL実行が必要な場合は,30,000回以下の単位でexecuteBatchメソッドを実行することを推奨します。

(f) 例外BatchUpdateExceptionで通知する更新カウント

バッチ更新実行時に発生する例外BatchUpdateExceptionの,getUpdateCountsメソッドの戻り値で通知する更新カウント(int型の配列)の内容を次の表に示します。

表18-56 getUpdateCountsメソッドの戻り値で通知する更新カウントの内容

バッチ更新の実行形態 BATCHEXCEPTION_BEHAVIOR※1の設定値
TRUE FALSE
配列機能を利用した一括実行 要素数0の配列 要素数nの配列
n:何回目のaddBatchで登録したパラメタでエラーになったかを示します。
エラーが発生するとロールバックされるため,すべての配列要素にはStatement.EXECUTE_FAILEDが設定されます。
JDBCドライバによる逐次実行 要素数が実行したSQL数の配列
各配列要素には更新行数※2を設定
要素数nの配列
n:何回目のaddBatchで登録したパラメタ又はSQLでエラーになったかを示します。
配列要素には次の値が設定されます。
要素0〜n-2:更新行数※2
要素n-1:Statement.EXECUTE_FAILED

注※1
次のどれかで指定します。
  • HiRDB接続時のユーザプロパティHiRDB_for_Java_BATCHEXCEPTION_BEHAVIOR
  • URLのBATCHEXCEPTION_BEHAVIOR
  • DataSource系インタフェースのsetBatchExceptionBehaviorメソッド
なお,接続先がバージョン08-01以前のHiRDBの場合,"TRUE"が指定されたものとして動作します。

注※2
CallableStatementクラスのexecuteBatchメソッドでCALL文を実行した場合,Statement.SUCCESS_NO_INFOを設定します。

更新カウントの例を次に示します。

配列機能を利用した一括実行のプログラム例

 
PreparedStatement pstmt = con.prepareStatement("INSERT INTO T1 VALUES(?,?)");
pstmt.setInt(1, 1);
pstmt.setString(2,"aaaa");
pstmt.addBatch();
pstmt.setInt(1, 2);
pstmt.setString(2,"bbbbbbbb");
pstmt.addBatch();.......................................[A]
pstmt.setInt(1, 3);
pstmt.setString(2,"cccc");
pstmt.addBatch();
pstmt.executeBatch();
 

JDBCドライバによる逐次実行のプログラム例

 
Statement stmt = con.createStatement();
stmt.addBatch("INSERT INTO T1 VALUES(1,'aaaa')");
stmt.addBatch("INSERT INTO T1 VALUES(2,'bbbbbbbb')");...[A]
stmt.addBatch("INSERT INTO T1 VALUES(3,'cccc')");
stmt.executeBatch();
 

プログラム例を実行し,[A]で登録したパラメタ,又はSQLの処理でエラーになった場合,getUpdateCountsメソッドで返却する更新カウントの内容を次に示します。

バッチ更新の実行形態 BATCHEXCEPTION_BEHAVIORの設定値
TRUE FALSE
配列機能を利用した一括実行 要素数0のint型の配列 要素数2のint型の配列
要素0の値:Statement.EXECUTE_FAILED
要素1の値:Statement.EXECUTE_FAILED
JDBCドライバによる逐次実行 要素数1のint型の配列
要素0の値:更新行数
要素数2のint型の配列
要素0の値:更新行数
要素1の値:Statement.EXECUTE_FAILED