본문 바로가기
실험실/db이행

Ora2Pg가 지원하는 SQL 변환 범위

by 죄니안죄니 2026. 1. 30.

❌ 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️⃣ 실무에서 가장 많이 쓰는 전략 (추천)

✅ 현실적인 베스트 프랙티스

  1. Ora2Pg로 DB 오브젝트 먼저 변환
  2. MyBatis XML SQL 전체 스캔
    • ROWNUM
    • NVL / DECODE
    • SYSDATE
    • (+)
    • DUAL
  3. 정규식 + 수동 리뷰 병행
  4. 쿼리 단위 테스트
    • “에러 안 남” ❌
    • 결과 동일성 검증
  5. 성능 확인 (특히 페이징 / 대량 조회)

6️⃣ 한 줄 요약 (이 질문의 정답)

  • Ora2Pg는 MyBatis XML SQL을 변환해주지 않는다
  • 이건 설계상 불가능한 영역이다
  • 대신
    • DB 오브젝트 변환
    • 위험 지점 가시화
    • 마이그레이션 기준점 제공
    • 까지는 아주 잘한다
  • *MyBatis SQL은 “사람이 책임지는 구간”**이다

댓글