Oracleデータベースの場合、IN句で1000件を超える項目を指定するとエラーになってしまうので、注意が必要である。
今回は、Spring Bootアプリケーション内でMyBatisフレームワークを利用する状態で、OracleのIN句で1000件の項目を指定した場合と、1000件を超える項目を指定した場合の動作を確認してみたので、共有する。
前提条件
下記記事の実装が完了していること。
PL/SQLによるデータ追加
Oracleデータベースに多数のデータを追加するには、PL/SQLブロックを利用すると便利である。user_dataテーブルのデータを削除し、1001件のデータを追加するPL/SQLプログラムの内容は、以下の通り。
1 2 3 4 5 6 7 8 | begin execute immediate 'TRUNCATE TABLE user_data'; for i in 1..1001 loop INSERT INTO user_data VALUES (i, 'テスト プリン' || TO_MULTI_BYTE(i), 2012, 1, 20, TO_CHAR(MOD(i, 2) + 1), 'テスト'); end loop; COMMIT; end; / |
上記PL/SQLプログラムを実行後の、データ数、idの最小・最大値、追加データの一部を確認した結果は、以下の通り。
1 | SELECT COUNT(*) FROM user_data |
1 | SELECT MIN(id), MAX(id) FROM user_data |
1 | SELECT * FROM user_data WHERE id <= 10 |
サンプルプログラムの作成
作成したサンプルプログラムの構成は以下の通り。
なお、上記の赤枠は、前提条件のプログラムから追加/変更したプログラムである。
application.propertiesの内容は以下の通りで、ログが見にくくなるため、SQLログ出力部分を削除している。
1 2 3 4 5 6 | server.port = 8084 # DB接続先 spring.datasource.url=jdbc:oracle:thin:@localhost:1521:xe spring.datasource.username=USER01 spring.datasource.password=USER01 spring.datasource.driverClassName=oracle.jdbc.driver.OracleDriver |
また、Spring Bootのメインクラスの内容は以下の通りで、IN句に1000件のデータを追加しSQLを実行した場合、IN句に1001件のデータを追加しSQLを実行した場合の処理を追加している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | package com.example.demo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import java.util.ArrayList; @SpringBootApplication public class DemoApplication implements CommandLineRunner { @Autowired private UserDataMapper userDataMapper; public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Override public void run(String... args) { // IN句を指定したSQLの実行結果を確認する // 引数のIDリストに1000件のデータを指定した場合 ArrayList<Long> idList = getIdListOneThousand(); System.out.println("*** 引数のIDリストに1000件のデータを指定した場合 ***"); System.out.println("*** idList size : " + idList.size()); ArrayList<UserData> userDataList = userDataMapper.findByIdList(idList); System.out.println("*** userDataList size : " + userDataList.size()); System.out.println(); // 引数のIDリストに1001件のデータを指定した場合 idList = getIdListOneThousandOne(); System.out.println("*** 引数のIDリストに1001件のデータを指定した場合 ***"); System.out.println("*** idList size : " + idList.size()); try{ userDataMapper.findByIdList(idList); }catch(Exception ex){ System.out.println("*** " + ex.getCause()); } } private ArrayList<Long> getIdListOneThousand(){ ArrayList<Long> idList = new ArrayList<>(); for(int i = 1; i <= 1000; i++){ idList.add(Long.valueOf(i)); } return idList; } private ArrayList<Long> getIdListOneThousandOne(){ ArrayList<Long> idList = getIdListOneThousand(); idList.add(Long.valueOf(1001)); return idList; } } |
その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-oracle-in-over1000/demo
サンプルプログラムの実行結果
Spring Bootのメインクラス(DemoApplication.java)を実行した結果、コンソールログに出力される内容は以下の通り。
上記実行結果の青枠部分で、IN句に1000件のデータを追加した場合に正常にSQLが実行されることが、赤枠部分で、IN句に1001件のデータを追加した場合にOracleエラーが発生することが、それぞれ確認できる。
要点まとめ
- Oracleデータベースの場合、IN句で1000件を超える項目を指定するとエラーになってしまうので、注意が必要である。