728x90
반응형
Oracle ORA-01795 에러 – IN 절 1000개 초과 시 발생하는 SQLSyntaxErrorException
1. 에러 개요
Spring 기반 애플리케이션에서 Oracle DB 쿼리를 실행하는 도중 아래와 같은 예외가 발생했습니다.
org.springframework.jdbc.BadSqlGrammarException:
### Error querying database.
Cause: java.sql.SQLSyntaxErrorException: ORA-01795: maximum number of expressions in a list is 1000
### The error may exist in URL [jar:file:/app.jar!/BOOT-INF/classes!/mapper/example-mapper.xml]
### The error may involve defaultParameterMap
### The error occurred while setting parameters
2. 원인
Oracle의 IN 절은 최대 1000개의 항목만 허용합니다. 이 제약을 초과할 경우 SQL 문이 무효로 간주되어 SQLSyntaxErrorException이 발생합니다.
3. 문제 쿼리 예시
SELECT item.COL1, item.COL2, test.COL3
FROM [TABLE]_ITEM item
RIGHT OUTER JOIN [TABLE] test ON test.KEY = item.KEY
WHERE item.KEY IN (?, ?, ..., ?);
4. 해결 방법 – 임시 테이블 활용
IN 절을 나누기보다 임시 테이블(Global Temporary Table)을 사용하는 방식이 대량 처리 시 성능과 유지보수 측면에서 더 적합합니다.
CREATE GLOBAL TEMPORARY TABLE TEMP_IDS (
ID NUMBER PRIMARY KEY
) ON COMMIT DELETE ROWS;
INSERT INTO TEMP_IDS (ID) VALUES (...);
SELECT item.*
FROM [TABLE]_ITEM item
JOIN TEMP_IDS temp ON item.KEY = temp.ID;
5. Java에서 임시 테이블 사용하는 예시
public void runWithTempTable(List<Long> ids) {
jdbcTemplate.batchUpdate("INSERT INTO TEMP_IDS (ID) VALUES (?)",
ids, 1000, (ps, id) -> ps.setLong(1, id));
List<Result> results = jdbcTemplate.query(
"SELECT ... FROM MAIN_TABLE m JOIN TEMP_IDS t ON m.ID = t.ID",
new BeanPropertyRowMapper<>(Result.class));
}
6. 분할 처리와 비교
| 항목 | IN 절 분할 | 임시 테이블 |
|---|---|---|
| 구현 난이도 | 낮음 | 중간 |
| 성능 (5천 건 이상) | 낮음 | 높음 |
| 실행 계획 최적화 | 불리함 | 유리함 |
| 쿼리 가독성 | 낮음 | 높음 |
| 실무 적합성 | 소량 요청 | 대량 처리 |
7. 정리
- Oracle IN 절은 1000개를 초과하면 ORA-01795 에러가 발생합니다.
- 대량의 ID를 조건으로 사용할 경우, 임시 테이블을 통한 JOIN 방식이 권장됩니다.
- Java에서는 batch insert와 JOIN 쿼리를 조합하여 안정적으로 처리할 수 있습니다.
반응형
'DataBase > Oracle' 카테고리의 다른 글
| Oracle|오라클 DB 버전 확인 방법 (0) | 2025.04.23 |
|---|---|
| [Oracle] 대량 데이터 인서트 하기 (Bulk Data Insert) (1) | 2022.08.03 |
댓글