Oracleデータベースの場合、IN句で1000件を超える項目を指定するとエラーになってしまうので、注意が必要である。
今回は、Spring Bootアプリケーション内でMyBatisフレームワークを利用する状態で、OracleのIN句で1000件の項目を指定した場合と、1000件を超える項目を指定した場合の動作を確認してみたので、共有する。
前提条件
下記記事の実装が完了していること。
PL/SQLによるデータ追加
Oracleデータベースに多数のデータを追加するには、PL/SQLブロックを利用すると便利である。user_dataテーブルのデータを削除し、1001件のデータを追加するPL/SQLプログラムの内容は、以下の通り。
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の最小・最大値、追加データの一部を確認した結果は、以下の通り。
SELECT COUNT(*) FROM user_data

SELECT MIN(id), MAX(id) FROM user_data

SELECT * FROM user_data WHERE id <= 10

サンプルプログラムの作成
作成したサンプルプログラムの構成は以下の通り。

なお、上記の赤枠は、前提条件のプログラムから追加/変更したプログラムである。
application.propertiesの内容は以下の通りで、ログが見にくくなるため、SQLログ出力部分を削除している。
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を実行した場合の処理を追加している。
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件を超える項目を指定するとエラーになってしまうので、注意が必要である。





