2011-09-15 6 views
0

이 질문의 목적을 위해 완전히 T-SQL에서 수행되는 ETL 프로세스가 있습니다. 추출 단계에서SQL Server Merge (정렬) 및 추적 업데이트

는, 현재의 프로세스는 다음과 같습니다

  1. 우리의 "소스"테이블
  2. 삽입 잘라 내기 우리의 "소스"테이블에 ODS 테이블의 모든 데이터

그러나, 나는 새로운 데이터를 삽입하고 변경된 데이터 만 업데이트하는 "증분 (incremental)"로드를 수행하는 기능을 구현하려고합니다.

  1. 설정 "아카이브" "소스"테이블의 비트 (모든 데이터가 현재 보관, 즉 변경) ODS에서
  2. 업데이트 기존의 데이터에 대한 "소스"(설정 갱신 된 행 : 그래서 그 과정은 다음과 같을 것 0 아카이브 비트) "소스"에 (아카이브 비트 0 ODS에서
  3. 삽입 새 데이터)

나는 SQL 서버 2008+의 MERGE 문 알고있다. 그러나, 내 관심은 올바르게 행이 실제로 변경된 것을 로깅 할 수있는 방법입니다. 단지 MERGE을 수행하면 데이터 자체가 변경되지 않아도 발견 된 모든 행이 변경된 것으로 표시됩니다.

업데이트 조건부의 모든 단일 열을 지정하는 것 외에이 작업을 수행 할 수있는 트릭이 있습니까? 아니면 내가하려는 일을 성취하기위한 더 좋은 과정이 있습니까? FWIW, 나는 내 통제를 벗어난 이유로 SSIS와 관련된 솔루션을 피하고 싶습니다.

답변

2

과거에는 ODS 테이블에 "operation"플래그를 구현하고 MERGE를 사용하여 원본과 ODS간에 변경된 사항이 있는지 확인했습니다. 이를 위해서는 고유 한 키와 소스의 시간 소인이 필요합니다. 타임 스탬프가 없다면 체크섬이나 비슷한 것을 사용할 수도 있지만 문제가 많습니다. 나는 "U"로 원본에서 새로운 타임 스탬프가있는 일치하는 레코드를 플래그로, "I"로 ODS에없는 레코드와 "D"로 원본에없는 ODS에있는 레코드에 플래그를 지정합니다. 그런 다음 ODS와 대상 테이블을 병합하는 별도의 절차를 시작합니다. 이 방법은 3 천만 -4 천만 개의 레코드 세트 중 1 박당 3-4K 만 변경해야하는 경우 매우 효과적이었습니다.

1

당신은 아마 변경 컬럼의 조건을 테스트 할 수 있습니다 : 어떤 경우에

MERGE TableA 
USING TableB 
ON TableA.Id = TableB.Id 
WHEN MATCHED AND (TableA.Column1 != TableB.Column1 OR TableA.Column2 != TableB.Column2 OR ....) 
    UPDATE SET TableA.Column1 = TableB.Column1, 
       TableA.Column2 = TableB.Column2 
WHEN NOT MATCHED BY TARGET THEN 
    INSERT VALUES (TableB.Id, TableB.Column1, TableB.Column2, ....); 

, 당신은 널 (NULL) 열이 더 조심해야합니다.

관련 문제