대량의 데이터를 데이터베이스에 자동으로 로드하기 시작한 이후로 잘못된 행을 기록할 필요성이 즉시 나타났습니다. 전통적으로 데이터 유효성 검사에 대한 제약 조건 (예: 데이터 유형 위반, 제약 조건 위반) 이 발생하면 오류가 있는 행 하나로 인해 전체 가져오기 프로세스가 중단되었습니다. 이로 인해 적절한 레코드와 부적절한 레코드가 모두 손실되었습니다.
문제는 최대한 많은 적절한 데이터를 로드하는 것뿐만 아니라 향후 수동 수정을 위한 감사 및 오류에 대한 자세한 설명을 남기는 것입니다. 단순히 "모두 롤백"하는 것이 아닙니다.
해결책: 일부 DBMS(예: PostgreSQL, SSIS가 포함된 SQL Server, EXTERNAL TABLES 도구가 있는 Oracle)에는 잘못된 행을 분리하여 로드하는 메커니즘이 있습니다. 범용적인 방법으로는 스테이징 테이블과 OUTER JOIN 및 NOT EXISTS를 통한 후속 업로드 유효성을 검증하며, 수동으로 문제 있는 행을 기록하는 "로그 테이블"을 사용합니다.
코드 예시:
-- 1. 임시 스테이징 테이블에 모든 데이터 로드 BULK INSERT staging_payments FROM 'payments.csv' WITH (...) -- 2. 올바른 데이터 필터링 INSERT INTO payments (id, amount, ...) SELECT id, amount, ... FROM staging_payments WHERE amount > 0 AND status IN ('approved', 'pending'); -- 3. 문제 있는 행을 별도의 테이블에 기록 INSERT INTO import_errors (row_data, error_desc) SELECT *, '잘못된 상태 또는 음수 금액' FROM staging_payments WHERE amount <= 0 OR status NOT IN ('approved', 'pending');
핵심 기능:
SQL 내부에서 ON ERROR RESUME NEXT를 통해 모든 것을 구현할 수 있나요?
SQL 표준은 대량 데이터 가져오기에 대한 유사한 구조를 포함하고 있지 않습니다. 대부분의 경우 오류 보고서는 외부 유틸리티나 위에서 설명한 로그 테이블에서 생성됩니다.
오류가 발생한 행만 롤백하기 위해 트랜잭션을 사용할 수 있나요?
트랜잭션의 롤백은 모든 행을 동시에 롤백합니다(원자성). 부분적으로 저장하는 것은 스테이징 테이블에 먼저 로드한 후 수동으로 성공적인 행을 commit하고 실패한 행을 기록하는 경우에만 가능합니다.
각 행에 대해 TRY/CATCH를 사용하여 INSERT 오류를 잡는 것이 비효율적인 이유는 무엇인가요?
수백만 행을 단일 INSERT + TRY/CATCH를 통해 순차적으로 처리하면 배치 또는 BULK INSERT + 로드 후 검증에 비해 성능이 급격히 저하됩니다.
한 회사가 INSERT 스크립트를 통해 수만 행을 로드하려 했고, 고유키의 오류로 인해 전체 배치가 롤백되었습니다. 이는 다운타임과 데이터 손실을 초래했습니다.
장점:
스테이징 테이블 사용, 오류 로그 및 입력 데이터를 "유효/무효" 카테고리로 구분함으로써 가져오기 속도를 높이고, 실패를 저장하고 자동으로 분석할 수 있었습니다.
장점: