Oracle Database 강좌

실무에서 유용한 Oracle 샘플 테이블과 MERGE INTO 활용 예제

_Blue_Sky_ 2025. 3. 7. 20:22
728x90
 

 
 
 
안녕하세요! 오늘은 Oracle 데이터베이스에서 실무적으로 사용할 수 있는 샘플 테이블을 만들고, MERGE INTO 문을 활용해 데이터를 효율적으로 병합하는 방법을 소개합니다. 실무에서는 테이블이 단순히 3~4개 컬럼으로 끝나는 경우는 드물죠. 그래서 이번 예제에서는 10개 컬럼으로 구성된 테이블과 **복합 기본 키(Composite Primary Key)**를 사용해 보겠습니다.
1. 샘플 테이블 설계
실무를 가정해 고객 주문 데이터를 다루는 테이블을 만들어 봅시다:
  • orders_target: 주문 데이터를 저장하는 대상 테이블
  • orders_source: 외부에서 가져온 주문 데이터를 임시로 저장하는 원본 테이블
 

 

728x90

 

-- 대상 테이블 생성 (orders_target)
CREATE TABLE orders_target (
    order_id NUMBER,              -- 주문 ID (복합 PKの一部)
    customer_id NUMBER,           -- 고객 ID (복합 PKの一部)
    order_date DATE,              -- 주문 날짜
    product_code VARCHAR2(10),    -- 제품 코드
    product_name VARCHAR2(100),   -- 제품 이름
    quantity NUMBER,              -- 주문 수량
    unit_price NUMBER,            -- 단가
    total_amount NUMBER,          -- 총액
    status VARCHAR2(20),          -- 주문 상태
    last_updated TIMESTAMP,       -- 최종 갱신 시간
    CONSTRAINT pk_orders_target PRIMARY KEY (order_id, customer_id) -- 복합 PK 설정
);

-- 원본 테이블 생성 (orders_source)
CREATE TABLE orders_source (
    order_id NUMBER,              -- 주문 ID
    customer_id NUMBER,           -- 고객 ID
    order_date DATE,              -- 주문 날짜
    product_code VARCHAR2(10),    -- 제품 코드
    product_name VARCHAR2(100),   -- 제품 이름
    quantity NUMBER,              -- 주문 수량
    unit_price NUMBER,            -- 단가
    total_amount NUMBER,          -- 총액
    status VARCHAR2(20),          -- 주문 상태
    last_updated TIMESTAMP        -- 최종 갱신 시간
);

-- 초기 데이터 삽입 (orders_target)
INSERT INTO orders_target VALUES (1001, 1, TO_DATE('2025-03-01', 'YYYY-MM-DD'), 'P001', '노트북', 1, 1500000, 1500000, '완료', SYSTIMESTAMP);
INSERT INTO orders_target VALUES (1002, 2, TO_DATE('2025-03-02', 'YYYY-MM-DD'), 'P002', '모니터', 2, 300000, 600000, '대기', SYSTIMESTAMP);

-- 원본 데이터 삽입 (orders_source)
INSERT INTO orders_source VALUES (1001, 1, TO_DATE('2025-03-01', 'YYYY-MM-DD'), 'P001', '노트북', 2, 1500000, 3000000, '완료', SYSTIMESTAMP); -- 갱신 대상
INSERT INTO orders_source VALUES (1003, 3, TO_DATE('2025-03-07', 'YYYY-MM-DD'), 'P003', '키보드', 5, 50000, 250000, '배송중', SYSTIMESTAMP); -- 삽입 대상

COMMIT;
설명:
  • order_idcustomer_id를 복합 기본 키로 설정해 주문과 고객을 고유하게 식별합니다.
  • 실무에서 자주 쓰이는 날짜, 금액, 상태 등의 컬럼을 추가했습니다.

 
728x90
 
2. MERGE INTO로 데이터 병합
이제 orders_source의 데이터를 orders_target에 병합합니다. 조건에 따라:
  • 동일한 order_idcustomer_id가 있으면 갱신하고,
  • 없으면 새로 삽입합니다.
MERGE INTO orders_target t
USING orders_source s
ON (t.order_id = s.order_id AND t.customer_id = s.customer_id)
WHEN MATCHED THEN
    UPDATE SET 
        t.order_date = s.order_date,
        t.product_code = s.product_code,
        t.product_name = s.product_name,
        t.quantity = s.quantity,
        t.unit_price = s.unit_price,
        t.total_amount = s.total_amount,
        t.status = s.status,
        t.last_updated = s.last_updated
WHEN NOT MATCHED THEN
    INSERT (t.order_id, t.customer_id, t.order_date, t.product_code, t.product_name, 
            t.quantity, t.unit_price, t.total_amount, t.status, t.last_updated)
    VALUES (s.order_id, s.customer_id, s.order_date, s.product_code, s.product_name, 
            s.quantity, s.unit_price, s.total_amount, s.status, s.last_updated);
실행 결과 확인:
SELECT * FROM orders_target;
 
ORDER_ID  CUSTOMER_ID  ORDER_DATE  PRODUCT_CODE  PRODUCT_NAME  QUANTITY  UNIT_PRICE  TOTAL_AMOUNT  STATUS  LAST_UPDATED
1001      1            2025-03-01  P001          노트북        2         1500000     3000000       완료    2025-03-07 ...
1002      2            2025-03-02  P002          모니터        2         300000      600000        대기    2025-03-07 ...
1003      3            2025-03-07  P003          키보드        5         50000       250000        배송중  2025-03-07 ...

3. 실무 팁
  • 성능 최적화: 대량 데이터 병합 시 인덱스를 order_idcustomer_id에 추가하면 성능이 향상됩니다.
  • 조건 추가: WHERE 절을 활용해 특정 상태(예: '배송중'만 갱신)로 필터링할 수 있습니다.
  • 에러 로깅: LOG ERRORS INTO를 추가해 병합 중 오류를 별도 테이블에 기록할 수 있습니다.
이렇게 하면 실무에서 자주 접하는 복잡한 데이터 병합 시나리오를 효율적으로 처리할 수 있습니다. 
728x90