❌ Ora2Pg는 MyBatis XML 안에 들어있는 SQL을 “자동으로 PostgreSQL 문법으로 변환해주지 않는다”.
이 영역은 도구의 지원 범위 밖이고, 사람이 직접 손봐야 하는 구간이야.
다만, Ora2Pg가 “어디를 손봐야 하는지 힌트는 줄 수는 있다” 정도로 이해하는 게 정확해.
아래에서 왜 그런지, 그리고 실무에서 어떻게 대응하는 게 맞는지를 단계적으로 정리할게.
1️⃣ Ora2Pg가 지원하는 SQL 변환 범위 (정확한 경계)
- *Ora2Pg**의 설계 철학부터 보면 이해가 쉬워.
Ora2Pg가 직접 변환하는 것
- Oracle DB 내부 오브젝트
- TABLE / VIEW / SEQUENCE
- FUNCTION / PROCEDURE / PACKAGE
- TRIGGER
- DB 안에 “저장된 SQL”만 대상임
즉,
- USER_SOURCE
- ALL_VIEWS
- ALL_TRIGGERS
- ALL_PROCEDURES
- 같은 Oracle 데이터 딕셔너리에서 꺼낼 수 있는 것들만 변환 대상
Ora2Pg가 ❌ 지원하지 않는 것
- 애플리케이션 소스 코드
- Java 코드
- MyBatis XML
- JPA @Query
- 배치 스크립트 안의 SQL
👉 이유는 단순해
Ora2Pg는 DB에 접속해서 DB 안에 있는 걸 읽는 도구지,
프로젝트 소스 트리를 파싱하는 도구가 아님.
2️⃣ 그럼 MyBatis XML의 SQL은 어떻게 해야 하느냐 (현실적인 답)
핵심 요약
- Ora2Pg = DB 스키마/로직 변환
- MyBatis XML = 애플리케이션 레이어 SQL → 수동 전환 필수
이걸 전제로 접근해야 삽질이 없어.
3️⃣ MyBatis XML에서 PostgreSQL로 바꾸면서 반드시 터지는 문법들
아래는 Oracle → PostgreSQL 마이그레이션 시 MyBatis에서 거의 100% 수정하는 항목들이야.
① ROWNUM / 페이징
-- Oracle
SELECT*
FROM (
SELECT A.*, ROWNUM RN
FROM TABLE_A A
ORDERBY A.CREATED_ATDESC
)
WHERE RNBETWEEN11AND20;
-- PostgreSQL
SELECT*
FROM TABLE_A
ORDERBY CREATED_ATDESC
LIMIT10OFFSET10;
📌 주의
- Oracle은 ROWNUM이 ORDER BY보다 먼저 적용되는 구조
- 그대로 기계적으로 바꾸면 결과가 달라짐
- 이건 Ora2Pg도 “경고만 하고 끝”임
② NVL / DECODE
-- Oracle
SELECT NVL(col,'N')FROMtable;
SELECT DECODE(status,'A',1,'B',2,0)FROMtable;
-- PostgreSQL
SELECTCOALESCE(col,'N')FROMtable;
SELECTCASE status
WHEN'A'THEN1
WHEN'B'THEN2
ELSE0
END
FROMtable;
📌 MyBatis XML엔 이런 게 수백 개씩 박혀 있는 경우가 많음
→ 일괄 치환 스크립트 + 사람 검증이 현실적인 해법
③ SYSDATE / SYSTIMESTAMP
-- Oracle
WHERE created_at>= SYSDATE-7
-- PostgreSQL
WHERE created_at>= now()-interval'7 days'
📌 Oracle DATE는 시간 포함, Postgres date는 아님
→ 타입에 따라 current_date vs now() 구분 필수
④ (+) OUTER JOIN 문법
-- Oracle
SELECT*
FROM A, B
WHERE A.ID= B.A_ID(+);
-- PostgreSQL
SELECT*
FROM A
LEFTJOIN BON A.ID= B.A_ID;
📌 이건 Ora2Pg가 DB VIEW 안에 있으면 바꿔주지만
📌 MyBatis XML 안에 있으면 절대 안 바꿔줌
⑤ 문자열 결합
-- Oracle
SELECT'A'||'B'FROM dual;
PostgreSQL에서도 ||는 가능하지만,
- 타입이 text가 아닐 경우
- 숫자/NULL 섞이면
- → 명시적 캐스팅 필요
⑥ DUAL 테이블
SELECT1FROM dual;
SELECT1;
📌 MyBatis에서 DUAL 남아 있으면 실행 즉시 에러
⑦ MERGE INTO
-- Oracle
MERGEINTO table_a t
USING table_b s
ON (t.id= s.id)
WHEN MATCHEDTHENUPDATE ...
WHENNOT MATCHEDTHENINSERT ...
-- PostgreSQL
INSERT INTO table_a (...)
SELECT ...
FROM table_b
ON CONFLICT (id)
DOUPDATESET ...
📌 구조 자체가 달라서 사람이 로직 재작성해야 함
4️⃣ Ora2Pg가 MyBatis SQL에 “도움은 되는 지점”
직접 변환은 안 하지만, 간접적으로는 큰 도움이 됨.
① Assessment 리포트
- Oracle 함수 사용 현황
- 패키지/프로시저 의존성
- Oracle 전용 문법 사용 비율
→ MyBatis SQL에서 터질 패턴을 미리 예측 가능
② DB 오브젝트 변환 결과와 비교
- VIEW / FUNCTION 변환 결과를 기준으로
- “이 쿼리는 애플리케이션에서도 같은 방식으로 고쳐야겠구나” 판단 가능
5️⃣ 실무에서 가장 많이 쓰는 전략 (추천)
✅ 현실적인 베스트 프랙티스
- Ora2Pg로 DB 오브젝트 먼저 변환
- MyBatis XML SQL 전체 스캔
- ROWNUM
- NVL / DECODE
- SYSDATE
- (+)
- DUAL
- 정규식 + 수동 리뷰 병행
- 쿼리 단위 테스트
- “에러 안 남” ❌
- 결과 동일성 검증 ⭕
- 성능 확인 (특히 페이징 / 대량 조회)
6️⃣ 한 줄 요약 (이 질문의 정답)
- Ora2Pg는 MyBatis XML SQL을 변환해주지 않는다
- 이건 설계상 불가능한 영역이다
- 대신
- DB 오브젝트 변환
- 위험 지점 가시화
- 마이그레이션 기준점 제공
- 까지는 아주 잘한다
- *MyBatis SQL은 “사람이 책임지는 구간”**이다
'실험실 > db이행' 카테고리의 다른 글
| Oracle SQL을 PostgreSQL SQL로 바꿀 때 MyBatis에서 자동 치환 가능한 것 / 절대 안 되는 것 목록 (1) | 2026.01.30 |
|---|---|
| 제로베이스 설치 시 보안 · 운영 · 이중화 전략 (0) | 2026.01.24 |
| Ora2Pg로 변환 후 “오브젝트별로” 직접 체크/수정해야 하는 포인트 정리 (0) | 2026.01.24 |
| 2컨테이너 실용화 (1) | 2026.01.22 |
| 결과파일의 관리 (0) | 2026.01.22 |
댓글