다음을 통해 공유


변경 데이터가 준비되었는지 확인

적용 대상: SQL Server Azure Data Factory의 SSIS Integration Runtime

변경 데이터의 증분 로드를 수행하는 통합 서비스 패키지의 제어 흐름 내에서 두 번째 작업은 선택한 간격에 대한 변경 데이터가 준비되었는지 확인하는 것입니다. 비동기 캡처 프로세스에서 선택한 엔드포인트까지 모든 변경 내용을 아직 처리하지 않았을 수 있으므로 이 단계가 필요합니다.

참고 항목

제어 흐름에 대한 첫 번째 태스크는 변경 간격의 엔드포인트를 계산하는 것입니다. 이 작업에 대한 자세한 내용은 변경 데이터 간격 지정을 참조하세요. 제어 흐름 디자인의 전체 프로세스에 대한 설명은 변경 데이터 캡처(SSIS)를 참조하세요.

솔루션의 구성 요소 이해

이 항목에 설명된 솔루션은 4개의 통합 서비스 구성 요소를 사용합니다.

  • SQL 실행 태스크의 출력을 반복적으로 평가하는 For Loop 컨테이너입니다.

  • 변경 데이터 캡처 프로세스가 유지 관리하는 특수 테이블을 쿼리한 다음 이 정보를 사용하여 데이터가 준비되었는지 여부를 확인하는 SQL 실행 태스크입니다.

  • 데이터가 준비되지 않은 경우 처리 지연을 구현하는 구성 요소입니다. 스크립트 작업 또는 SQL 실행 작업일 수 있습니다.

  • 필요 시, SQL 실행 작업이 오류 또는 시간 제한 조건을 나타내는 값을 반환할 때 오류 또는 시간 제한을 보고하는 구성 요소입니다.

이러한 구성 요소는 루프 내부 및 패키지의 뒷부분에서 실행 흐름을 제어하기 위해 여러 패키지 변수의 값을 설정하거나 읽습니다.

패키지 변수를 설정하려면

  1. SQL Server Data Tools(SSDT)의 Variables 창에서 다음 변수를 생성합니다.

    1. SQL 실행 작업에서 반환하는 상태 값을 저장할 정수 데이터 형식의 변수를 만듭니다.

      이 예에서는 초기 값이 0인 변수 이름으로 DataReady를 사용합니다.

    2. 데이터가 준비되지 않은 경우 지연 기간 동안 보류하는 변수를 만듭니다. 스크립트 작업을 사용하여 지연을 구현하려는 경우 변수에 정수 데이터 형식 정수가 있어야 합니다. WAITFOR 문이 있는 SQL 실행 태스크를 사용하려는 경우에는 "00:00:10"과 같은 값을 허용하기 위해 변수의 데이터 형식이 string이어야 합니다.

      이 예에서는 초기 값이 10인 변수 이름으로 DelaySeconds를 사용합니다.

    3. 루프의 현재 반복을 보관할 integer 데이터 형식의 변수를 만듭니다.

      이 예에서는 초기 값이 0인 변수 이름으로 TimeoutCount를 사용합니다.

    4. 시간 제한 조건을 보고하기 전에 루프에서 데이터를 테스트해야 하는 횟수를 지정하는 정수 데이터 형식의 변수를 만듭니다.

      이 예에서는 초기 값이 20인 변수 이름으로 TimeoutCeiling를 사용합니다.

    5. (선택 사항) 변경 데이터의 첫 번째 로드를 나타내는 데 사용할 수 있는 정수 데이터 형식의 변수를 만듭니다.

      이 예제에서는 변수 이름인 IntervalID를 사용하고, 초기기 로드를 나타내기 위한 0의 값만 확인합니다.

For 루프 컨테이너 구성

변수를 설정한 경우 For 루프 컨테이너가 추가될 첫 번째 구성 요소입니다.

변경 데이터가 준비될 때까지 대기하도록 For 루프 컨테이너를 구성하기

  1. SSIS 디자이너의 제어 흐름 탭에서 제어 흐름에 For 루프 컨테이너를 추가합니다.

  2. 간격의 엔드포인트를 계산하는 SQL 실행 태스크를 For 루프 컨테이너에 연결합니다.

  3. For 루프 편집기에서 다음 옵션을 선택합니다.

    1. InitExpression의 경우 @DataReady = 0를(을) 입력합니다.

      이 식은 루프 변수의 초기 값을 설정합니다.

    2. EvalExpressionm의 경우 @DataReady == 0를(을) 입력합니다.

      이 식이 False로 평가되면 실행이 루프에서 전달되고 증분 로드가 시작됩니다.

변경 데이터를 쿼리하는 SQL 실행 작업 구성

For 루프 컨테이너 내에 SQL 실행 작업을 추가합니다. 이 작업은 변경 데이터 캡처 프로세스가 데이터베이스에서 유지 관리하는 테이블을 쿼리합니다. 이 쿼리의 결과는 변경 데이터가 준비되었는지 여부를 나타내는 상태 값입니다.

다음 표의 첫 번째 열은 샘플 Transact-SQL 쿼리에 의해 SQL 실행 태스크에서 반환된 값을 보여줍니다. 두 번째 열은 다른 구성 요소에서 이러한 값에 응답하는 방식을 보여 줍니다.

Return Value 의미 Response
0 변경 데이터가 준비되지 않았음을 나타냅니다.

선택한 간격의 끝 지점 뒤에 오는 변경 데이터 캡처 레코드가 없습니다.
지연을 구현하는 구성 요소로 실행을 계속합니다. 그런 다음 반환된 값이 0인 경우 컨트롤이 For 루프 컨테이너로 돌아갑니다. 이 컨테이너는 SQL 실행 작업을 계속 확인합니다.
1 변경 데이터가 전체 간격 동안 캡처되지 않았거나 삭제되었음을 나타낼 수 있습니다. 이는 오류 상태로 처리됩니다.

선택한 간격의 시작 지점보다 앞에 오는 변경 데이터 캡처 레코드가 없습니다.
오류를 기록하는 선택적 구성 요소에서 실행이 계속됩니다.
2 데이터가 준비되었음을 나타냅니다.

변경 데이터 캡처 레코드는 선택한 구간의 시작점보다 앞에 있고 종료점보다 뒤에 있습니다.
실행이 For 루프 밖으로 전달되고 증분 로드가 시작됩니다.
3 사용 가능한 모든 변경 데이터의 초기 로드를 나타냅니다.

조건부 논리는 이 용도로만 사용되는 특수 패키지 변수에서 이 값을 가져옵니다.
실행이 For 루프 밖으로 전달되고 증분 로드가 시작됩니다.
5 TimeoutCeiling에 도달했음을 나타냄

루프에서 지정한 횟수만큼 데이터를 테스트했으며 데이터를 여전히 사용할 수 없습니다. 이 테스트나 유사한 테스트를 사용하지 않으면 패키지가 무기한 실행될 수 있습니다.
시간 제한을 기록하는 선택적 구성 요소에서 실행이 계속됩니다.

변경 데이터가 준비되었는지 여부를 쿼리하도록 SQL 실행 작업을 구성하기

  1. For 루프 컨테이너 내에 SQL 실행 작업을 추가합니다.

  2. SQL 실행 태스크 편집기일반 페이지에서 다음 옵션을 선택합니다.

    1. ResultSet의 경우 단일 행을 선택합니다.

    2. 원본 데이터베이스에 대한 유효한 연결을 구성합니다.

    3. SQLSourceType의 경우 직접 입력을 선택합니다.

    4. SQLStatement에 다음 SQL 문을 입력합니다.

      declare @DataReady int, @TimeoutCount int  
      
      if not exists (select tran_end_time from cdc.lsn_time_mapping  
              where tran_end_time > ?  )  
          select @DataReady = 0  
      else  
          if ? = 0  
              select @DataReady = 3   
      else  
          if not exists (select tran_end_time from cdc.lsn_time_mapping  
                  where tran_end_time <= ? )  
              select @DataReady = 1   
      else  
          select @DataReady = 2  
      
      select @TimeoutCount = ?  
      if (@DataReady = 0)  
          select @TimeoutCount = @TimeoutCount + 1  
      else  
          select @TimeoutCount = 0  
      
      if (@TimeoutCount > ?)  
          select @DataReady = 5  
      
      select @DataReady as DataReady, @TimeoutCount as TimeoutCount  
      
      
  3. SQL 실행 태스크 편집기매개 변수 매핑페이지에서 다음 매핑을 만듭니다.

    1. ExtractEndTime 변수를 매개 변수 0에 매핑합니다.

    2. IntervalID 변수를 매개 변수 1에 매핑합니다.

    3. ExtractStartTime 변수를 매개 변수 2에 매핑합니다.

    4. TimeoutCount 변수를 매개 변수 3에 매핑합니다.

    5. TimeoutCeiling 변수를 매개 변수 4에 매핑합니다.

  4. SQL 실행 작업 편집기결과 집합 페이지에서 DataReady 결과를 DataReady 변수에 매핑하고 TimeoutCount 결과를 TimeoutCount 변수에 매핑합니다.

변경 데이터가 준비될 때까지 대기

변경 데이터가 준비되지 않은 경우 지연을 구현하는 여러 가지 방법 중 하나를 사용할 수 있습니다. 다음 두 절차에서는 스크립트 작업 또는 SQL 실행 작업을 사용하여 지연을 구현하는 방법을 보여 줍니다.

참고 항목

미리 컴파일된 스크립트는 SQL 실행 태스크보다 적은 오버헤드를 발생시킵니다.

스크립트 태스크를 사용하여 지연을 구현하려면

  1. For 루프 컨테이너 내에 스크립트 작업을 추가합니다.

  2. 쿼리하는 SQL 실행 작업을 연결하여 변경 데이터가 새 스크립트 작업에 대해 준비되었는지 여부를 확인합니다.

  3. SQL 실행 작업을 스크립트 작업에 연결하는 선행 제약 조건의 경우 선행 제약 조건 편집기를 열고 다음 옵션을 선택합니다.

    1. 평가 작업의 경우 식 및 제약 조건을 선택합니다.

    2. 의 경우 성공을 선택합니다.

      성공 의 제약 조건 값은 이전 태스크의 성공을 참조합니다. 이 경우 SQL 실행 작업 성공입니다.

    3. 에 대해 @DataReady == 0 && @TimeoutCount <= @TimeoutCeiling를(을) 입력합니다.

    4. 아직 선택하지 않은 경우 Logical AND, All Constraints는 True로 평가해야 합니다를 선택합니다.

  4. 스크립트 작업 편집기에서 스크립트 페이지의 ReadOnlyVariables에 대해 목록에서 User::DelaySeconds 정수 변수를 선택합니다.

  5. 스크립트 작업 편집기스크립트 페이지에서 스크립트 편집을 클릭하여 스크립트 개발 환경을 엽니다.

  6. 기본 절차에서 다음 코드 줄 중 하나를 입력합니다.

    • C#에서 프로그래밍하는 경우 다음 코드 행을 입력합니다.

      System.Threading.Thread.Sleep((int)Dts.Variables["DelaySeconds"].Value * 1000);  
      

      - 또는 -

    • Visual Basic에서 프로그래밍하는 경우 다음 코드 행을 입력합니다.

      System.Threading.Thread.Sleep(Ctype(Dts.Variables("DelaySeconds").Value, Integer) * 1000)  
      
      

      참고 항목

      Thread.Sleep 메서드는 밀리초 단위로 지정된 인수를 예상합니다.

  7. 스크립트 실행에서 DtsExecResult.Success를 반환하는 기본 코드 줄을 그대로 둡니다.

  8. 스크립트 개발 환경 및 스크립트 태스크 편집기를 닫습니다.

스크립트 실행 작업을 사용하여 지연 구현하기

  1. For 루프 컨테이너 내에 SQL 실행 작업을 추가합니다.

  2. 쿼리하는 SQL 실행 작업을 연결하여 변경 데이터가 새 스크립트 실행 작업에 대해 준비되었는지 여부를 확인합니다.

  3. 두 SQL 실행 작업을 연결하는 선행 제약 조건의 경우 선행 제약 조건 편집기를 열고 다음 옵션을 선택합니다.

    1. 평가 작업의 경우 식 및 제약 조건을 선택합니다.

    2. 의 경우 성공을 선택합니다.

      성공 의 제약 조건 값은 이전 SQL 실행 태스크의 성공을 참조합니다.

    3. 에 대해 @DataReady == 0를(을) 입력합니다.

    4. 아직 선택하지 않은 경우 Logical AND, All Constraints는 True로 평가해야 합니다를 선택합니다.

      이 옵션을 선택하려면 두 가지 조건인 제약 조건과 식이 모두 true여야 합니다.

  4. SQL 실행 태스크 편집기일반 페이지에서 다음 옵션을 선택합니다.

    1. ResultSet의 경우 단일 행을 선택합니다.

    2. 원본 데이터베이스에 대한 유효한 연결을 구성합니다.

    3. SQLSourceType의 경우 직접 입력을 선택합니다.

    4. SQLStatement에 다음 SQL 문을 입력합니다.

      WAITFOR DELAY ?  
      
      
  5. 편집기의 매개 변수 매핑 페이지에서 DelaySeconds 문자열 변수를 매개 변수 0에 매핑합니다.

오류 조건 처리

루프 내에 추가 구성 요소를 구성하여 오류 또는 시간 초과 상태를 기록할 수도 있습니다.

  • 이 구성 요소는 DataReady 변수의 값이 1일 때 오류 조건을 기록할 수 있습니다. 이 값은 선택한 간격이 시작되기 전에 사용 가능한 변경 데이터가 없음을 나타냅니다.

  • 이 구성 요소는 TimeoutCeiling 변수의 값에 도달할 때 시간 제한 조건을 기록할 수도 있습니다. 이 값은 루프에서 지정한 횟수만큼 데이터를 테스트했으며 데이터를 여전히 사용할 수 없음을 나타냅니다. 이 테스트나 유사한 테스트를 사용하지 않으면 패키지가 무기한 실행될 수 있습니다.

오류 조건을 기록하도록 선택적 스크립트 작업을 구성하기

  1. 로그에 메시지를 작성하여 오류 또는 시간 제한을 보고하려면 패키지에 대한 로깅을 구성합니다. 자세한 내용은 SQL Server 데이터 도구에서 패키지 로깅 사용을 참조하세요.

  2. For 루프 컨테이너 내에 스크립트 작업을 추가합니다.

  3. 쿼리하는 SQL 실행 작업을 연결하여 변경 데이터가 새 스크립트 작업에 대해 준비되었는지 여부를 확인합니다.

  4. SQL 실행 작업을 스크립트 작업에 연결하는 선행 제약 조건의 경우 선행 제약 조건 편집기를 열고 다음 옵션을 선택합니다.

    1. 평가 작업의 경우 식 및 제약 조건을 선택합니다.

    2. 의 경우 성공을 선택합니다.

      성공 의 제약 조건 값은 이전 태스크의 성공을 참조합니다. 이 경우 SQL 실행 작업 성공입니다.

    3. 에 대해 @DataReady == 1 || @DataReady == 5를(을) 입력합니다.

    4. 아직 선택하지 않은 경우 Logical AND, All Constraints는 True로 평가해야 합니다를 선택합니다.

      이 옵션을 선택하려면 두 가지 조건인 제약 조건과 식이 모두 true여야 합니다.

  5. 스크립트 작업 편집기의 편집기 스크립트 페이지에서 ReadOnlyVariables에 대해 목록에서 User::DataReadyUser::ExtractStartTime을 선택하여 해당 값을 스크립트에 사용할 수 있도록 합니다.

    로그에 기록하는 정보에 특정 시스템 변수(예: System::PackageName)의 정보를 포함하려는 경우 해당 변수도 선택합니다.

  6. 스크립트 작업 편집기스크립트 페이지에서 스크립트 편집을 클릭하여 스크립트 개발 환경을 엽니다.

  7. 기본 절차에서 Dts.Log 메서드를 호출하여 오류를 기록하거나 Dts.Events 인터페이스의 메서드 중 하나를 호출하여 이벤트를 발생하도록 코드를 입력합니다. Dts.TaskResult = Dts.Results.Failure를 반환하여 패키지에 오류를 알립니다.

    다음 샘플에서는 로그에 메시지를 쓰는 방법을 보여줍니다. 자세한 내용은 스크립트 작업의 로깅, 스크립트 작업에서 이벤트 발생스크립트 작업의 결과 반환을 참조하세요.

    ' User variables.  
    Dim dataReady As Integer = _  
      CType(Dts.Variables("DataReady").Value, Integer)  
    Dim extractStartTime As Date = _  
      CType(Dts.Variables("ExtractStartTime").Value, DateTime)  
    
    ' System variables.  
    Dim packageName As String = _  
      Dts.Variables("PackageName").Value.ToString()  
    Dim executionStartTime As Date = _  
      CType(Dts.Variables("StartTime").Value, DateTime)  
    
    Dim eventMessage As New System.Text.StringBuilder()  
    
    If dataReady = 1 OrElse dataReady = 5 Then  
    
      If dataReady = 1 Then  
        eventMessage.AppendLine("Start Time Error")  
      Else  
        eventMessage.AppendLine("Timeout Error")  
      End If  
    
      With eventMessage  
        .Append("The package ")  
        .Append(packageName)  
        .Append(" started at ")  
        .Append(executionStartTime.ToString())  
        .Append(" and ended at ")  
        .AppendLine(DateTime.Now().ToString())  
        If dataReady = 1 Then  
          .Append("The specified ExtractStartTime was ")  
          .AppendLine(extractStartTime.ToString())  
        End If  
      End With  
    
      System.Windows.Forms.MessageBox.Show(eventMessage.ToString())  
    
      Dts.Log(eventMessage.ToString(), 0, Nothing)  
    
      Dts.TaskResult = Dts.Results.Failure  
    
    Else  
    
      Dts.TaskResult = Dts.Results.Success  
    
    End If  
    
    
  8. 스크립트 개발 환경 및 스크립트 태스크 편집기를 닫습니다.

다음 단계

변경 데이터가 준비되었는지 확인한 후 다음 단계는 변경 데이터에 대한 쿼리를 준비하는 것입니다.

다음 주제: 변경 데이터에 대한 쿼리 준비