데이터베이스 연구실.log

이행 검증과 점검 리포트

이행 전후 건수, 합계, 날짜와 문자 길이 비교, 표본 및 업무 쿼리와 권한 점검으로 찾은 프로시저 누락

validatechecker.py건수합계날짜 최소, 최대문자 길이PK 표본AS-IS/TO-BEhas_table_privilegeROWNUMLIMIT

#핵심 요약

실습 도구는 두 단계로 확인함
⑤ 검증은 테이블 데이터의 건수와 합계를, ⑥ AS-IS/TO-BE 점검은 오브젝트, 데이터 표본, PL/SQL, 업무 쿼리, 권한 다섯 관점을 봄

건수만 같아서는 부족함
숫자 반올림, 시간 손실, 문자 잘림을 잡으려고 합계, 날짜 최소, 최대, 문자, LOB 길이 합을 함께 비교함

권한은 목록만 보지 않고 has_table_privilege 같은 함수로 그 계정이 정말 그 일을 할 수 있는지 묻음

실습은 첫 점검에서 프로시저 누락과 그 EXECUTE 권한 누락 2건을 찾고, 조치 후 다섯 관점 모두 100%로 통과했음

#개념과 동작 원리

#⑤ 데이터 검증 항목

검사 Oracle PostgreSQL 잡아내는 문제
건수 count(*) count(*) 빠진 행, 중복 행
숫자 합계(최대 3개) sum(컬럼) sum(컬럼) 소수점 손실, 반올림
날짜 최소, 최대 min / max min / max 시, 분, 초 손실, 시간대 밀림
문자 길이 합 sum(length()) sum(char_length()) 한글 깨짐, 잘림
LOB 길이 합 sum(dbms_lob.getlength()) sum(char_length()) CLOB 잘림

실습 결과는 검사 14개(CUST 6, ORDERS 8) 모두 일치, 검증 리포트는 CSV로 내려받음

#⑥ AS-IS/TO-BE 점검 관점

관점 AS-IS(Oracle) TO-BE(PostgreSQL) 비교 방법
오브젝트 ALL_TABLES, ALL_VIEWS, ALL_SEQUENCES, ALL_CONSTRAINTS, ALL_OBJECTS pg_class, pg_constraint, pg_proc, pg_trigger 이름 대조(누락, 추가)
데이터 count(*)와 PK 표본 5행 count(*)와 같은 PK 5행 건수, 표본 행의 모든 컬럼 값
PL/SQL ALL_SOURCE(VALID/INVALID) pg_get_functiondef 대상 스키마에 있는지, 다른 스키마에 변환본이 있는지
업무 쿼리 Oracle SQL 같은 질문의 PostgreSQL SQL 결과 행을 순서까지 비교
권한 ALL_TAB_PRIVS has_table_privilege, has_sequence_privilege, has_function_privilege 그 계정이 실제로 그 일을 할 수 있는지

실습 첫 점검: 오브젝트 7/8, 데이터 100%, PL/SQL 0%, 업무 쿼리 100%, 권한 8/9
조치 목록은 프로시저 누락과 EXECUTE 권한 누락이었음
실습에서는 예제2에서 ora2pg로 변환해 둔 다른 스키마의 프로시저를 도구의 가져오기 버튼으로 대상 스키마에 만들고 EXECUTE 권한을 줬음
다시 점검하자 오브젝트 8/8, 데이터 2/2, PL/SQL 1/1, 업무 쿼리 7/7, 권한 9/9가 됐음
점검 보고서는 HTML로 내려받음

원래 파일 맡은 일
engine.py 검증 validate
checker.py 점검 objects, data, plsql, copy_routine, preset_queries, query, privs
app.py ⑤ 검증 표, ⑥ 점검 탭과 보고서 화면

#필수 명령어 또는 SQL

#PostgreSQL 쪽 직접 확인

psql (대상 계정)조회만 함
\dt <SCHEMA>.*
\d <SCHEMA>.orders
select count(*) from <SCHEMA>.cust;
select count(*) from <SCHEMA>.orders;
select count(*), sum(total_amt) from <SCHEMA>.v_cust_sales;
select * from <SCHEMA>.v_cust_sales order by cust_id limit 3;
select last_value from <SCHEMA>.orders_seq;
DB 서버 OS조회만 함
psql -h localhost -U <USERNAME> <DB_NAME> -e -f mm_pg_check.sql

결과 해석: 실습 결과는 CUST 100,000, ORDERS 1,000,000, 뷰 100,000행에 합계 250444357921.73, 시퀀스 last_value 1000001임
-e는 실행한 SQL을 결과 앞에 찍지만 \dt, \d 같은 메타 명령은 찍지 않음

#Oracle 쪽 같은 값 확인

SQL*Plus (소스 계정)현재 세션 설정만 변경함
set lines 120
set numwidth 20
col cust_nm format a20
select count(*) from cust;
select count(*) from orders;
select count(*), sum(total_amt) from v_cust_sales;
select * from v_cust_sales order by cust_id fetch first 3 rows only;

결과 해석: 건수, 뷰 합계, 앞 3행이 PostgreSQL과 같음
set numwidth 20이 없으면 합계가 지수 형식으로 찍힘

#업무 쿼리 비교: 매출 상위 고객 5명

SQL*Plus (소스 계정)조회만 함
select * from (
  select c.cust_id, c.cust_nm, sum(o.amount) amt
    from cust c join orders o on o.cust_id = c.cust_id
   group by c.cust_id, c.cust_nm
   order by amt desc, c.cust_id)
 where rownum <= 5
psql (대상 계정)조회만 함
select c.cust_id, c.cust_nm, sum(o.amount) amt
  from cust c join orders o on o.cust_id = c.cust_id
 group by c.cust_id, c.cust_nm
 order by amt desc, c.cust_id
 limit 5

결과 해석: 실습에서는 두 결과가 5행 순서까지 같다고 적었음
금액이 같을 때를 대비해 c.cust_id로 순서를 고정함

#권한이 실제로 같은지

SQL*Plus (소스 계정)조회만 함
select grantee, table_name, privilege from user_tab_privs_made order by grantee, table_name, privilege;
select object_name, object_type, status from user_objects where object_type = 'PROCEDURE';
psql (대상 계정)조회만 함
\dp <SCHEMA>.*
\df <SCHEMA>.*
select has_table_privilege('<REPORT_USER>', '<SCHEMA>.cust', 'SELECT')  as report_select,
       has_table_privilege('<REPORT_USER>', '<SCHEMA>.cust', 'INSERT')  as report_insert,
       has_function_privilege('<USERNAME>', '<SCHEMA>.p_upgrade_grade(bigint)', 'EXECUTE') as user_execute;

결과 해석: Oracle 쪽은 10행이 나오지만 PUBLIC ... INHERIT PRIVILEGES는 12c부터 사용자마다 자동으로 생기는 권한이라 이행 대상에서 빠져 9건이 됨
PostgreSQL 쪽은 t, f, t로, 보고용 역할은 SELECT만 받았음
\dp의 글자는 r=SELECT, a=INSERT, w=UPDATE, d=DELETE, D=TRUNCATE, x=REFERENCES, t=TRIGGER, U=USAGE임

#가져온 프로시저 비교

psql (대상 계정)조회만 함
\sf <SCHEMA>.p_upgrade_grade

결과 해석: Oracle 실습 8줄과 비교하면 NUMBER 인자가 bigint로, 본문의 테이블 이름이 대상 스키마로 바뀌었고 나머지 로직은 같음
Oracle 실습에서는 USER_SOURCE에서 줄 번호 순으로 읽음(객체 상태와 소스 조회)

#사용 조건과 주의사항

문자 길이 비교에 CHAR 컬럼을 쓰면 값이 다름
Oracle length()는 CHAR의 뒷공백까지 세고 PostgreSQL char_length()는 char(n)의 뒷공백을 빼고 셈
실습에서는 문자 길이 검사를 VARCHAR2 컬럼만 대상으로 함

where rownum <= 3 order by...는 아무 행을 고른 뒤 정렬함
정렬한 안쪽 쿼리를 감싸 밖에서 자르거나 fetch first(12c 이상)를 씀

두 드라이버가 돌려주는 값의 모양(CHAR 뒷공백, 10과 10.00, 날짜 타입)이 달라 표본 행이 다르게 나올 수 있음
실습에서는 비교 전에 뒷공백 제거, 숫자 Decimal 정규화, 날짜 ISO 문자열로 맞춤

ora2pg 변환본은 본문에도 원래 스키마 이름이 박혀 있어, 그대로 가져오면 다른 스키마의 테이블을 고침
실습에서는 정의 전체의 스키마 접두어를 대상 스키마로 바꾸고 \sf로 확인함

PostgreSQL에서 대상 계정으로 테이블을 만들면 그 계정이 소유자라 Oracle보다 권한이 많게 보임(arwdDxt)
실습에서는 이를 "일치(소유자)"로 보고, 소유자를 바꾸려면 이행 후 alter table ... owner to를 쓴다고 적었음

표본 5행 비교는 표본임
실습의 "운영 전환 가능" 판정이 모든 행의 일치를 뜻하지는 않음

SEO_HKabsumveritas@gmail.comBuilt with Claude Code & Codex

마지막 갱신 개인 학습 기록이며 운영 환경 적용 전 공식 문서 확인 필요

두 글자 이상 입력, 위아래 화살표로 이동하고 Enter로 열기