# Oracle 계보 (As-Is) — acquire-core-x > **이 시스템의 원본은 Oracle 이다.** BC 매입시스템 As-Is 는 Oracle 19c + Pro\*C + > Tuxedo/ATMI 였고(BAIS RFI 기준), 본 저장소의 현행 코드는 그 시스템을 오픈 스택 > (Enduro/X + ECPG + PostgreSQL)으로 **이식한 1차 이관본**이다. Klaro Forge 가 > 수행할 다음 이관은 이 레거시 → Java Spring Boot 다. > > `legacy-oracle/` 에 **As-Is Oracle Pro\*C 역사 원본**을 보존한다(컴파일 대상 아님). > 현행 이식본(`app/src/**/*.pgc`, ECPG/PostgreSQL)과 1:1로 대조 가능하다. ## 3단 계보 ``` ┌── As-Is ───────────┐ ┌── 현행(1차 이관본) ─────┐ ┌── To-Be (Forge) ──────┐ │ Oracle 19c │ │ PostgreSQL 16 │ │ PostgreSQL 16 │ │ Pro*C (proc) │ → │ ECPG (EXEC SQL) │ → │ JPA / MyBatis │ │ Tuxedo/ATMI │ │ Enduro/X (open ATMI) │ │ Spring Boot 3.x │ │ PL/SQL 패키지 │ │ (패키지→서비스 인라인) │ │ @Service / @Transactional │ legacy-oracle/*.pc │ │ app/src/**/*.pgc │ │ (target) │ └─────────────────────┘ └─────────────────────────┘ └────────────────────────┘ ``` - As-Is → 현행: **DB 엔진 이관**(Oracle→PostgreSQL)은 끝났다. Oracle 방언·Pro\*C·PL/SQL 패키지를 PostgreSQL/ECPG 로 옮긴 결과가 현행 코드다. - 현행 → To-Be: 남은 난제는 **애플리케이션 계층**(ATMI·임베디드SQL·UBF·XA)이며, 이게 Forge 가 다룰 대상이다. DB 엔진은 이미 PostgreSQL 이라 To-Be 와 일치한다. ## Oracle → PostgreSQL 방언 이관 매핑 (1차 이관에서 실제로 옮긴 것들) | Oracle (As-Is, Pro\*C) | PostgreSQL (현행, ECPG) | 이관 난이도·주의 | |---|---|---| | `VARCHAR2(n)` / Pro\*C `VARCHAR h[n]` | `TEXT` / `char h[n]` | 널·공백 트림 의미 차이 | | `NVL(x, d)` | `COALESCE(x, d)` | 인자 개수 차이(NVL2→CASE) | | `DECODE(e, k1,v1, k2,v2, d)` | `CASE WHEN e=k1 THEN v1 ... ELSE d END` | 다분기 전개, NULL 동등성 차이 | | `SYSDATE` / `SYSTIMESTAMP` | `now()` / `current_date` | 시간대·타입 차이 | | `... FROM DUAL` | (FROM 절 생략) | 시퀀스·스칼라 조회 재작성 | | `seq.NEXTVAL` / `seq.CURRVAL` | `nextval('seq')` / `currval('seq')` | 문법·세션 시맨틱 차이 | | `ROWNUM = 1` / `ROWNUM <= n` | `LIMIT 1` / `LIMIT n` | ROWNUM 은 정렬 前 적용 → 의미 함정 | | 외부조인 `t1.a (+) = t2.b` | `LEFT/RIGHT JOIN ... ON` | 구식 `(+)` 전면 재작성 | | `CONNECT BY PRIOR` 계층질의 | `WITH RECURSIVE` CTE | 계층 재귀 완전 재작성(최난이도) | | `TO_DATE(s,'YYYYMMDD')` / `TO_CHAR(d,fmt)` | `to_date`/`to_char` (포맷토큰 일부 상이) | 포맷 마스크 검증 필요 | | `(+)`/`MINUS`/`ROWID` | `EXCEPT`/`ctid`(비권장) | 세트연산·행식별자 대체 | | Pro\*C `EXEC SQL WHENEVER SQLERROR GOTO` | ECPG 동일 문 + `sqlca.sqlcode` 분기 | 라벨분기 유지 가능 | | Pro\*C `EXEC SQL INCLUDE oraca` / `EXEC ORACLE OPTION` | (해당 없음) | Oracle 전용 진단영역 제거 | | **PL/SQL 패키지** (`pkg_x.proc`) | ECPG 서비스 인라인 / 함수 | 패키지 상태·오버로드 소실, 로직 서비스로 흡수 | | `RAISE_APPLICATION_ERROR(-20001,...)` | `RAISE EXCEPTION` / 리턴코드 | 예외 프로토콜 재설계 | | `UTL_FILE` 파일 I/O | 서버 파일 I/O / COPY | 배치 파일생성 재작성 | ## As-Is 원본 보존 목록 (`legacy-oracle/`) | 원본 (Oracle Pro\*C / PL-SQL) | 현행 이식본 (ECPG) | 업무 | |---|---|---| | `proc/ACQUIRE.pc` | `app/src/ac/svc/ACQUIRE.pgc` | 매입 접수 | | `proc/AUTH_APPROVE.pc` | `app/src/au/svc/AUTH_APPROVE.pgc` | 승인 확정 | | `proc/ST_MDR.pc` | `app/src/st/svc/ST_MDR.pgc` | MDR 수수료 기표 | | `proc/SETTLE.pc` | `app/src/st/svc/SETTLE.pgc` | 정산 확정 | | `proc/RECONCILE.pc` | `app/src/rc/svc/RECONCILE.pgc` | 대사 (CONNECT BY) | | `proc/CL_DAILY.pc` | `app/src/cl/svc/CL_DAILY.pgc` | 일마감 배치 | | `proc/PAY_FILEGEN.pc` | `app/src/py/svc/PAY_FILEGEN.pgc` | 지급파일 생성 배치 | | `plsql/PKG_SETTLE.sql` | (서비스로 인라인) | 정산 PL/SQL 패키지 | | `plsql/PKG_LEDGER.sql` | (서비스로 인라인) | 원장 기표 PL/SQL 패키지 | ## 왜 DB 는 PostgreSQL 인가 (Oracle 로 되돌리지 않는 이유) - **To-Be 가 PostgreSQL** 이다(BAIS RFI: Oracle 19c → PostgreSQL 16). DB 이관은 이미 완료 상태로 두고, Forge 가 다룰 **애플리케이션 이관**(ATMI/임베디드SQL/UXA)에 집중한다. - 라이선스·재현성: 오픈 스택이라 `docker compose up` 한 번으로 어디서든 실동작. - 마이그레이션 난이도의 본질은 DB 엔진이 아니라 그 위의 Pro\*C·Tuxedo·XA 계층이며, 그 난이도는 위 원본들에서 그대로 확인된다.