티스토리 뷰

Database/Oracle

(Oracle) Bulk Collect & FORALL 예제

데브포유 2026. 8. 19. 11:22
반응형
DECLARE
    -- 1. 커서 정의
    CURSOR c_target_data IS
        SELECT * FROM employees;
        
    -- 2. 커서 행 구조에 맞는 컬렉션 타입 정의
    TYPE t_emp_list IS TABLE OF c_target_data%ROWTYPE;
    v_emp_list t_emp_list;
    
    -- 한 번에 처리할 건수 지정
    v_limit_size CONSTANT NUMBER := 5000; 
BEGIN
    OPEN c_target_data;
    
    LOOP
        -- 3. LIMIT 크기만큼 나누어서 SELECT
        FETCH c_target_data 
        BULK COLLECT INTO v_emp_list 
        LIMIT v_limit_size;
        
        -- 컬렉션에 데이터가 있다면 INSERT 수행
        IF v_emp_list.COUNT > 0 THEN
            -- 4. FORALL로 대량 INSERT
            FORALL i IN 1 .. v_emp_list.COUNT
                INSERT INTO employees_history 
                VALUES v_emp_list(i);
                
            -- 주기적인 COMMIT으로 롤백 세그먼트 부하 감소
            COMMIT; 
        END IF;
        
        -- 5. 커서에 더 이상 가져올 데이터가 없으면 루프 종료
        EXIT WHEN c_target_data%NOTFOUND;
    END LOOP;
    
    CLOSE c_target_data;
    DBMS_OUTPUT.PUT_LINE('대용량 데이터 이관 완료');
EXCEPTION
    WHEN OTHERS THEN
        IF c_target_data%ISOPEN THEN
            CLOSE c_target_data;
        END IF;
        ROLLBACK;
        DBMS_OUTPUT.PUT_LINE('오류 발생: ' || SQLERRM);
END;
/
반응형