다음을 통해 공유


로컬 패키지의 출력 로드

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

클라이언트 애플리케이션은 출력이 ADO.NET 사용하여 SQL Server 대상에 저장되거나 출력이 System.IO 네임스페이스의 클래스를 사용하여 플랫 파일 대상에 저장되는 경우 Integration Services 패키지의 출력을 읽을 수 있습니다. 그러나 클라이언트 애플리케이션은 데이터를 유지하기 위한 중간 단계 없이 메모리에서 직접 패키지의 출력을 읽을 수도 있습니다. 이 솔루션의 핵심은 System.Data 네임스페이스의 IDbConnection, IDbCommandIDbDataParameter 인터페이스의 특수한 구현을 포함하는 Microsoft.SqlServer.Dts.DtsClient 네임스페이스입니다. 어셈블리 Microsoft.SqlServer.Dts.DtsClient.dll %ProgramFiles%\Microsoft SQL Server\100\DTS\Binn에 기본적으로 설치됩니다.

Important

라이브러리를 사용하는 DtsClient 이 문서에 설명된 절차는 패키지 배포 모델(즉, , /DTS또는 /File 옵션 포함)으로 배포된 패키지에 /SQL대해서만 작동합니다. 이 절차는 서버 배포 모델(즉, /ISServer 옵션)을 사용하여 배포된 패키지에서는 작동하지 않습니다. 서버 배포 모델(즉, /ISServer 옵션)을 통해 배포된 로컬 패키지의 출력을 사용하려면 이 문서의 설명된 절차 대신 데이터 스트리밍 대상을 사용합니다.

참고 항목

이 항목에 설명된 절차에서는 데이터 흐름 태스크 및 부모 개체의 DelayValidation 속성을 기본값인 False로 설정해야 합니다.

설명

이 절차에서는 메모리에서 직접 DataReader 대상을 사용하여 패키지의 출력을 로드하는 관리 코드에서 클라이언트 애플리케이션을 개발하는 방법을 보여 줍니다. 여기에 요약된 단계는 다음 코드 샘플에 설명되어 있습니다.

데이터 패키지 출력을 클라이언트 애플리케이션으로 로드하려면

  1. 패키지에서 클라이언트 애플리케이션에 읽으려는 출력을 수신하도록 DataReader 대상을 구성합니다. 나중에 클라이언트 애플리케이션에서 이 이름을 사용하므로 DataReader 대상에 설명이 포함된 이름을 지정합니다. DataReader 대상의 이름을 기록해 둡다.

  2. 개발 프로젝트에서 어셈블리 Microsoft.SqlServer.Dts.DtsClient.dll 찾아 Microsoft.SqlServer.Dts.DtsClient 네임스페이스에 대한 참조를 설정합니다. 기본적으로 이 어셈블리는 C:\Program Files\Microsoft SQL Server\100\DTS\Binn에 설치됩니다. C# Using 또는 Visual Basic Imports 문을 사용하여 네임스페이스를 코드로 가져옵니다.

  3. 코드에서 dtexec.exe 패키지를 실행하는 데 필요한 명령줄 매개 변수가 포함된 연결 문자열 사용하여 DtsClient.DtsConnection 형식의 개체를 만듭니다. 자세한 내용은 dtexec Utility를 참조하세요. 그런 다음 이 연결 문자열을 사용하여 연결을 엽니다. dtexecui 유틸리티를 사용하여 필요한 연결 문자열 시각적으로 만들 수도 있습니다.

    참고 항목

    샘플 코드는 구문을 사용하여 파일 시스템에서 패키지를 로드하는 방법을 /FILE <path and filename> 보여 줍니다. 그러나 구문을 사용하거나 구문을 사용하여 /SQL <package name> /DTS \<folder name>\<package name> Integration Services 패키지 저장소에서 MSDB 데이터베이스에서 패키지를 로드할 수도 있습니다.

  4. 이전에 만든 DtsConnection을 사용하는 DtsClient.DtsCommand 형식의 개체를 만들고 해당 CommandText 속성을 패키지의 DataReader 대상 이름으로 설정합니다. 그런 다음 명령 개체의 ExecuteReader 메서드를 호출하여 패키지 결과를 새 DataReader로 로드합니다.

  5. 필요에 따라 DtsCommand 개체의 DtsDataParameter 개체 컬렉션을 사용하여 패키지의 출력을 간접적으로 매개 변수화하여 패키지에 정의된 변수에 값을 전달할 수 있습니다. 패키지 내에서 이러한 변수를 쿼리 매개 변수로 사용하거나 식에서 DataReader 대상으로 반환된 결과에 영향을 줄 수 있습니다. 클라이언트 애플리케이션의 DtsDataParameter 개체와 함께 사용하려면 먼저 DtsClient 네임스페이스의 패키지에서 이러한 변수를 정의해야 합니다. (다음을 클릭해야 할 수 있습니다.변수 창에서 변수 도구 모음 단추를 선택하여 네임스페이 열을 표시합니다.) 클라이언트 코드에서 DtsCommand의 Parameters 컬렉션에 DtsDataParameter를 추가할 때 변수 이름에서 DtsClient 네임스페이스 참조를 생략합니다. 예시:

    command.Parameters.Add(new DtsDataParameter("MyVariable", 1));  
    
  6. 필요에 따라 DataReader의 Read 메서드를 반복적으로 호출하여 출력 데이터의 행을 반복합니다. 클라이언트 애플리케이션에서 데이터를 사용하거나 나중에 사용할 수 있는 데이터를 저장합니다.

    Important

    이 DataReader 구현의 Read 메서드는 마지막 데이터 행을 읽은 후 한 번 더 true를 반환 합니다. 따라서 Read가 true를 반환하는 동안 DataReader를 반복하는 일반적인 코드를 사용하기가 어렵습니다. 코드가 읽기 메서드에 대한 추가 최종 호출 없이 예상 행 수를 읽은 후 DataReader 또는 연결을 닫으려고 하면 코드에서 처리되지 않은 예외가 발생합니다. 그러나 Read가 여전히 true를 반환하지만 마지막 행이 전달된 경우에 코드에서 이 마지막 루프 반복의 데이터를 읽으려고 하면 "SSIS IDataReader가 결과 집합의 끝을 지났습니다."라는 메시지와 함께 처리되지 않은 ApplicationException이 발생합니다. 이 동작은 다른 DataReader 구현의 동작과는 다릅니다. 따라서 읽기가 true를 반환하는 동안 루프를 사용하여 DataReader의 행을 읽는 경우 마지막으로 성공한 Read 메서드 호출에서 이 예상 ApplicationException을 catch, 테스트 및 삭제하는 코드를 작성해야 합니다. 또는 예상되는 행 수를 미리 알고 있는 경우 행을 처리한 다음 DataReader 및 연결을 닫기 전에 Read 메서드를 한 번 더 호출할 수 있습니다.

  7. DtsCommand 개체의 Dispose 메서드를 호출합니다. 이는 DtsDataParameter 개체를 사용한 경우에 특히 중요합니다.

  8. DataReader와 연결 개체를 닫습니다.

예시

다음 예제에서는 단일 집계 값을 계산하고 DataReader 대상에 값을 저장하는 패키지를 실행한 다음 DataReader에서 이 값을 읽고 Windows Form의 텍스트 상자에 값을 표시합니다.

클라이언트 애플리케이션에 패키지의 출력을 로드할 때는 매개 변수를 사용할 필요가 없습니다. 매개 변수를 사용하지 않으려면 DtsClient 네임스페이스에서 변수 사용을 생략하고 DtsDataParameter 개체를 사용하는 코드를 생략할 수 있습니다.

테스트 패키지를 만들려면

  1. 새 Integration Services 패키지를 만듭니다. 샘플 코드는 패키지 이름으로 "DtsClientWParamPkg.dtsx"를 사용합니다.

  2. DtsClient 네임스페이스에 String 형식의 변수를 추가합니다. 샘플 코드는 변수 이름으로 Country를 사용합니다. (다음을 클릭해야 할 수 있습니다.변수 창에서 변수 도구 모음 단추를 선택하여 네임스페이 열을 표시합니다.)

  3. AdventureWorks2022 샘플 데이터베이스에 연결하는 OLE DB 연결 관리자를 추가합니다.

  4. 패키지에 데이터 흐름 태스크를 추가하고 데이터 흐름 디자인 화면으로 전환합니다.

  5. 데이터 흐름에 OLE DB 원본을 추가하고 이전에 만든 OLE DB 연결 관리자와 다음 SQL 명령을 사용하도록 구성합니다.

    SELECT * FROM Sales.vIndividualCustomer WHERE CountryRegionName = ?  
    
  6. 매개 변수를 클릭하고 쿼리 매개 변수 설정 대화 상자에서 쿼리 매개 변수0의 단일 입력 매개 변수를 DtsClient::Country 변수에 매핑합니다.

  7. 데이터 흐름에 집계 변환을 추가하고 OLE DB 원본의 출력을 변환에 연결합니다. 집계 변환 편집기를 열고 이 변환에서 모든 입력 열(*)에 대해 "Count all" 연산을 수행하고 집계된 값을 CustomerCount라는 별칭으로 출력하도록 구성합니다.

  8. 데이터 흐름에 DataReader 대상을 추가하고 집계 변환의 출력을 DataReader 대상에 연결합니다. 샘플 코드는 DataReader의 이름으로 "DataReaderDest"를 사용합니다. 대상에 대해 사용 가능한 단일 입력 열인 CustomerCount를 선택합니다.

  9. 패키지를 저장합니다. 다음에 만든 테스트 애플리케이션은 패키지를 실행하고 메모리에서 직접 출력을 검색합니다.

테스트 애플리케이션을 만들려면

  1. 새 Windows Forms 애플리케이션을 만듭니다.

  2. %ProgramFiles%\Microsoft SQL Server\100\DTS\Binn에서 같은 이름의 어셈블리로 이동하여 Microsoft.SqlServer.Dts.DtsClient 네임스페이스에 대한 참조를 추가합니다.

  3. 다음 샘플 코드를 복사하여 양식의 코드 모듈에 붙여넣습니다.

  4. dtexec.exe 패키지를 실행하는 데 필요한 명령줄 매개 변수를 포함하도록 필요에 따라 dtexecArgs 변수 값을 수정합니다. 샘플 코드는 파일 시스템에서 패키지를 로드합니다.

  5. 패키지에 DataReader 대상의 이름을 포함할 수 있도록 필요에 따라 dataReaderName 변수의 값을 수정합니다.

  6. 폼에 단추와 입력란을 추가합니다. 샘플 코드는 단추 이름으로 btnRun을 사용하고 txtResults를 텍스트 상자의 이름으로 사용합니다.

  7. 애플리케이션을 실행하고 단추를 클릭합니다. 패키지가 실행되는 동안 잠시 일시 중지한 후 양식의 텍스트 상자에 패키지(캐나다 고객 수)가 계산한 집계 값이 표시됩니다.

예제 코드

Imports System.Data  
Imports Microsoft.SqlServer.Dts.DtsClient  
  
Public Class Form1  
  
  Private Sub btnRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRun.Click  
  
    Dim dtexecArgs As String  
    Dim dataReaderName As String  
    Dim countryName As String  
  
    Dim dtsConnection As DtsConnection  
    Dim dtsCommand As DtsCommand  
    Dim dtsDataReader As IDataReader  
    Dim dtsParameter As DtsDataParameter  
  
    Windows.Forms.Cursor.Current = Cursors.WaitCursor  
  
    dtexecArgs = "/FILE ""C:\...\DtsClientWParamPkg.dtsx"""  
    dataReaderName = "DataReaderDest"  
    countryName = "Canada"  
  
    dtsConnection = New DtsConnection()  
    With dtsConnection  
      .ConnectionString = dtexecArgs  
      .Open()  
    End With  
  
    dtsCommand = New DtsCommand(dtsConnection)  
    dtsCommand.CommandText = dataReaderName  
  
    dtsParameter = New DtsDataParameter("Country", DbType.String)  
    dtsParameter.Direction = ParameterDirection.Input  
    dtsCommand.Parameters.Add(dtsParameter)  
  
    dtsParameter.Value = countryName  
  
    dtsDataReader = dtsCommand.ExecuteReader(CommandBehavior.Default)  
  
    With dtsDataReader  
      .Read()  
      txtResults.Text = .GetInt32(0).ToString("N0")  
    End With  
  
    'After reaching the end of data rows,  
    ' call the Read method one more time.  
    Try  
      dtsDataReader.Read()  
    Catch ex As Exception  
      MessageBox.Show("Exception on final call to Read method:" & ControlChars.CrLf & _  
      ex.Message & ControlChars.CrLf & _  
      ex.InnerException.Message, "Exception on final call to Read method", _  
      MessageBoxButtons.OK, MessageBoxIcon.Error)  
    End Try  
  
    ' The following method is a best practice, and is  
    '  required when using DtsDataParameter objects.  
    dtsCommand.Dispose()  
  
    Try  
      dtsDataReader.Close()  
    Catch ex As Exception  
      MessageBox.Show("Exception closing DataReader:" & ControlChars.CrLf & _  
      ex.Message & ControlChars.CrLf & _  
      ex.InnerException.Message, "Exception closing DataReader", _  
      MessageBoxButtons.OK, MessageBoxIcon.Error)  
    End Try  
  
    Try  
      dtsConnection.Close()  
    Catch ex As Exception  
      MessageBox.Show("Exception closing connection:" & ControlChars.CrLf & _  
      ex.Message & ControlChars.CrLf & _  
      ex.InnerException.Message, "Exception closing connection", _  
      MessageBoxButtons.OK, MessageBoxIcon.Error)  
    End Try  
  
    Windows.Forms.Cursor.Current = Cursors.Default  
  
  End Sub  
  
End Class  
using System;  
using System.Windows.Forms;  
using System.Data;  
using Microsoft.SqlServer.Dts.DtsClient;  
  
namespace DtsClientWParamCS  
{  
  public partial class Form1 : Form  
  {  
    public Form1()  
    {  
      InitializeComponent();  
      this.btnRun.Click += new System.EventHandler(this.btnRun_Click);  
    }  
  
    private void btnRun_Click(object sender, EventArgs e)  
    {  
      string dtexecArgs;  
      string dataReaderName;  
      string countryName;  
  
      DtsConnection dtsConnection;  
      DtsCommand dtsCommand;  
      IDataReader dtsDataReader;  
      DtsDataParameter dtsParameter;  
  
      Cursor.Current = Cursors.WaitCursor;  
  
      dtexecArgs = @"/FILE ""C:\...\DtsClientWParamPkg.dtsx""";  
      dataReaderName = "DataReaderDest";  
      countryName = "Canada";  
  
      dtsConnection = new DtsConnection();  
      {  
        dtsConnection.ConnectionString = dtexecArgs;  
        dtsConnection.Open();  
      }  
  
      dtsCommand = new DtsCommand(dtsConnection);  
      dtsCommand.CommandText = dataReaderName;  
  
      dtsParameter = new DtsDataParameter("Country", DbType.String);  
      dtsParameter.Direction = ParameterDirection.Input;  
      dtsCommand.Parameters.Add(dtsParameter);  
  
      dtsParameter.Value = countryName;  
  
      dtsDataReader = dtsCommand.ExecuteReader(CommandBehavior.Default);  
  
      {  
        dtsDataReader.Read();  
        txtResults.Text = dtsDataReader.GetInt32(0).ToString("N0");  
      }  
  
      //After reaching the end of data rows,  
      // call the Read method one more time.  
      try  
      {  
        dtsDataReader.Read();  
      }  
      catch (Exception ex)  
      {  
        MessageBox.Show(  
          "Exception on final call to Read method:\n" + ex.Message + "\n" + ex.InnerException.Message,  
          "Exception on final call to Read method", MessageBoxButtons.OK, MessageBoxIcon.Error);  
      }  
  
      // The following method is a best practice, and is  
      //  required when using DtsDataParameter objects.  
      dtsCommand.Dispose();  
  
      try  
      {  
        dtsDataReader.Close();  
      }  
      catch (Exception ex)  
      {  
        MessageBox.Show(  
          "Exception closing DataReader:\n" + ex.Message + "\n" + ex.InnerException.Message,  
          "Exception closing DataReader", MessageBoxButtons.OK, MessageBoxIcon.Error);  
      }  
  
      try  
      {  
        dtsConnection.Close();  
      }  
      catch (Exception ex)  
      {  
        MessageBox.Show(  
          "Exception closing connection:\n" + ex.Message + "\n" + ex.InnerException.Message,  
          "Exception closing connection", MessageBoxButtons.OK, MessageBoxIcon.Error);  
      }  
  
      Cursor.Current = Cursors.Default;  
  
    }  
  }  
}  

참고 항목

로컬 실행과 원격 실행의 차이점 이해
프로그래밍 방식으로 로컬 패키지 로드 및 실행
프로그래밍 방식으로 원격 패키지 로드 및 실행