Oracle Database を利用していると、SQL 実行時に
ORA-01795 : リストに指定できる式の最大数は1000です。
というエラーが発生することがあります。
このエラーは一見すると分かりにくいものの、原因は明確で、発生条件も限られています。
しかし、業務システムやバッチ処理などで大量データを扱う場面では非常に起こりやすく、適切な対処方法を理解していないと、無理な修正やパフォーマンス低下を招く恐れがあります。
本記事では、ORA-01795 が発生する正確な原因と、現場でよく使われる対処方法を、実務目線で分かりやすく解説します。

ORA-01795 エラーとは何か
ORA-01795 は、IN 句などのリスト指定において、1000 個を超える式を指定した場合に発生する Oracle 固有の制限エラーです。
Oracle Database では、SQL 文の中で以下のような書き方をした場合、
1つのリストに指定できる値の上限は 1000 個まで
という制限が設けられています。
SELECT *
FROM employees
WHERE employee_id IN (1, 2, 3, ..., 1001);
このように、IN 句の中に 1001 個以上の値を並べると、SQL は実行前にエラーとして拒否され、ORA-01795 が返されます。
エラーが発生する主な原因
ORA-01795 が発生する原因は、ほぼ以下のケースに集約されます。
1. IN 句に 1000 件を超える値を指定している
最も典型的な原因です。
アプリケーション側で取得した ID リストや、バッチ処理で生成した配列をそのまま SQL に渡している場合に発生しやすくなります。
特に以下のようなケースでは注意が必要です。
- CSV やファイルから読み込んだ ID をそのまま IN 句に展開している
- 画面検索条件で大量のチェックボックス選択を許可している
- サブシステムから受け取った ID リストを加工せずに使用している
2. サブクエリの結果が 1000 件を超えている(誤解されやすい点)
ORA-01795 は サブクエリの結果件数が 1000 件を超えた場合に直接発生するわけではありません。
ただし、以下のように サブクエリの結果をアプリ側で展開し、IN 句として再利用している場合はエラーになります。
WHERE col IN (:id1, :id2, :id3, ...);
Code language: CSS (css)
サブクエリ自体が原因ではなく、「最終的に SQL 文として 1000 件超のリストになっている」ことが原因です。
3. フレームワークや ORM が内部的に IN 句を生成している
Java + MyBatis、Hibernate、Spring JDBC などを使用している場合、
コレクションをそのままバインドすると、内部的に IN 句へ展開されます。
開発者が直接 SQL を書いていなくても、結果的に 1000 件超の IN 句が生成され、ORA-01795 が発生することがあります。
なお、Oracle では IN 句や WHERE 句の書き方を誤った場合、
ORA-01795 とは別に構文エラーが発生することもあります。
特に多いのが、条件式の不足や記述ミスによって発生する
「ORA-00936: 式がありません」エラーです。
SQL の具体的な誤り例と修正方法については、
以下の記事で詳しく解説しています。
ORA-01795 の代表的な対処方法
ここからは、実務でよく採用される対処方法を具体的に解説します。
対処方法1:IN 句を分割して OR 条件でつなぐ
最も単純で、緊急対応として使われる方法です。
WHERE col IN (1~1000)
OR col IN (1001~2000)
1000 件以内に分割することで、エラーを回避できます。
メリット
- 実装が簡単
- 既存 SQL の修正量が少ない
デメリット
- SQL が長くなり、可読性が低下する
- 条件が増えるとパフォーマンスに影響が出る可能性がある
対処方法2:一時表(グローバル一時表)を使用する
大量データを扱う場合に、最も推奨される方法です。
- ID を一時表に INSERT
- JOIN で参照する
SELECT t.*
FROM target_table t
JOIN temp_ids i ON t.id = i.id;
メリット
- 件数制限を受けない
- パフォーマンスが安定しやすい
- SQL がシンプルになる
デメリット
- 一時表の管理が必要
- トランザクション設計に注意が必要
対処方法3:サブクエリを直接使用する
IN 句に直接値を並べるのではなく、サブクエリとして記述します。
WHERE col IN (
SELECT id
FROM another_table
);
この書き方では 1000 件制限は適用されません。
注意点
- サブクエリのパフォーマンスに注意
- 実行計画の確認は必須
対処方法4:EXISTS 句に書き換える
IN 句の代替として EXISTS を使用する方法です。
WHERE EXISTS (
SELECT 1
FROM temp_ids t
WHERE t.id = main.id
);
メリット
- 件数制限なし
- 大量データに強い
デメリット
- 書き方に慣れが必要
- 実行計画の理解が求められる
対処方法5:アプリケーション側で制御する
- 1000 件ごとに分割して SQL を発行
- バッチ処理としてループ処理を行う
即効性はありますが、設計としては最後の手段です。
ORA-01795 を回避する設計上の注意点
- 大量データを IN 句で処理しない
- ID リストは表として扱う
- 将来的な件数増加を考慮する
- ORM 任せにしないで、生成される SQL を必ず確認する
よくある質問(Q & A)
- Oracle のバージョンによって制限は変わりますか?
-
いいえ。Oracle Database では長年この制限は変わっていません。
- サブクエリでも 1000 件制限はありますか?
-
サブクエリ自体には制限はありません。IN 句に直接値を列挙した場合のみ制限されます。
- 1000 件ちょうどなら問題ありませんか?
-
はい。1000 件までは問題なく実行できます。
- パフォーマンス面で最もおすすめの対処法は?
-
一時表を使用した JOIN が最も安定します。
- EXISTS と IN はどちらが良いですか?
-
データ量が多い場合は EXISTS の方が有利になるケースが多いです。
まとめ
ORA-01795 は Oracle の仕様による制限であり、バグではありません。
原因を正しく理解すれば、回避方法はいくつも存在します。
特に、大量データを扱うシステムでは IN 句に値を並べる設計自体を見直すことが重要です。
一時表や JOIN、EXISTS を活用し、将来的な拡張にも耐えられる SQL 設計を行いましょう。



