스크립트 구성 요소를 사용하여 원본 만들기
Integration Services 패키지의 데이터 흐름에서 원본 구성 요소를 사용하여 데이터 원본의 데이터를 로드하고 다운스트림 변환 및 대상에 전달할 수 있습니다. 일반적으로 데이터 원본에 연결하는 데는 기존 연결 관리자를 사용합니다.
스크립트 구성 요소에 대한 개요는 스크립트 구성 요소를 사용하여 데이터 흐름 확장을 참조하십시오.
스크립트 구성 요소 및 해당 구성 요소가 생성하는 인프라 코드를 사용하면 사용자 지정 데이터 흐름 구성 요소를 개발하는 과정이 훨씬 간단해집니다. 하지만 스크립트 구성 요소의 작동 방식을 이해하려면 사용자 지정 데이터 흐름 구성 요소를 개발하는 데 필요한 단계를 파악하는 것이 좋습니다. 사용자 지정 데이터 흐름 구성 요소 개발 섹션과 이 섹션의 사용자 지정 원본 구성 요소 개발 항목을 참조하십시오.
원본 구성 요소 시작
SSIS 디자이너의 데이터 흐름 창에 스크립트 구성 요소를 추가하면 원본, 대상 또는 변환 스크립트를 선택하기 위한 스크립트 구성 요소 유형 선택 대화 상자가 열립니다. 이 대화 상자에서 원본을 선택합니다.
메타데이터 디자인 모드에서 원본 구성 요소 구성
원본 구성 요소를 만들도록 선택한 후에는 스크립트 변환 편집기를 사용하여 구성 요소를 구성합니다. 자세한 내용은 스크립트 구성 요소 편집기에서 스크립트 구성 요소 구성을 참조하십시오.
데이터 흐름 원본 구성 요소는 입력을 사용하지 않으며 하나 이상의 출력을 지원합니다. 구성 요소의 출력을 구성하는 것은 사용자 지정 스크립트를 작성하기 전에 메타데이터 디자인 모드에서 스크립트 변환 편집기를 사용하여 완료해야 하는 단계 중 하나입니다.
스크립트 변환 편집기의 스크립트 페이지에서 ScriptLanguage 속성을 설정하여 스크립트 언어를 지정할 수도 있습니다.
[!참고]
스크립트 구성 요소 및 스크립트 태스크에 대한 기본 스크립트 언어를 설정하려면 옵션 대화 상자의 일반 페이지에서 스크립트 언어 옵션을 사용합니다. 자세한 내용은 일반 페이지를 참조하십시오.
연결 관리자 추가
일반적으로 원본 구성 요소는 기존 연결 관리자를 사용하여 데이터 흐름으로 로드할 데이터가 있는 데이터 원본에 연결합니다. 적절한 연결 관리자를 추가하려면 스크립트 변환 편집기의 연결 관리자 페이지에서 추가를 클릭합니다.
그러나 연결 관리자는 단지 특정 유형의 데이터 원본에 연결하는 데 필요한 정보를 캡슐화하고 저장하는 편리한 단위일 뿐입니다. 데이터를 로드하거나 저장하고 또한 데이터 원본에 대한 연결을 열고 닫는 사용자 지정 코드는 개발자가 직접 작성해야 합니다.
스크립트 구성 요소에서 연결 관리자를 사용하는 방법은 스크립트 구성 요소에서 데이터 원본에 연결을 참조하십시오.
스크립트 변환 편집기의 연결 관리자 페이지에 대한 자세한 내용은 스크립트 변환 편집기(연결 관리자 페이지)를 참조하십시오.
출력 및 출력 열 구성
원본 구성 요소는 입력을 사용하지 않으며 하나 이상의 출력을 지원합니다. 스크립트 변환 편집기의 입/출력 페이지에는 기본적으로 단일 출력이 만들어져 있지만 출력 열은 만들어져 있지 않습니다. 편집기의 이 페이지에서 다음과 같은 항목을 구성할 수 있습니다.
각 출력에 대해 수동으로 출력 열을 추가하고 구성해야 합니다. 각 출력에 대한 출력 열 폴더를 선택하고 열 추가 및 열 제거 단추를 사용하여 원본 구성 요소의 각 출력에 대한 출력 열을 관리합니다. 나중에 스크립트에서는 자동 생성 코드에서 만들어진 형식화된 접근자 속성을 사용하여 출력을 여기에서 할당한 이름으로 참조합니다.
예기치 않은 값이 포함된 행에 대한 시뮬레이션된 오류 출력과 같은 추가 출력을 하나 이상 만들 수 있습니다. 원본 구성 요소의 출력을 관리하려면 출력 추가 및 출력 제거 단추를 사용합니다. 각 행을 동일한 ExclusionGroup 값을 공유하는 출력 중 하나로만 전송하려는 경우 사용 가능한 모든 출력의 ExclusionGroup 속성에 0이 아닌 동일한 값을 지정하지 않으면 모든 입력 행이 사용 가능한 모든 출력으로 전송됩니다. ExclusionGroup을 식별하기 위해 선택한 특정 정수 값은 중요하지 않습니다.
[!참고]
모든 행을 출력하지 않으려는 경우 단일 출력과 함께 0이 아닌 ExclusionGroup 속성 값을 사용할 수도 있습니다. 그러나 이 경우 출력으로 보낼 각 행에 대해 DirectRowTo<outputbuffer> 메서드를 명시적으로 호출해야 합니다.
출력에 이름을 지정할 수 있습니다. 나중에 스크립트에서는 자동 생성 코드에서 만들어진 형식화된 접근자 속성을 사용하여 출력을 이름으로 참조합니다.
일반적으로 동일한 ExclusionGroup의 여러 출력에는 동일한 출력 열이 있습니다. 그러나 시뮬레이션된 오류 출력을 만드는 경우 오류 정보를 저장할 다른 열을 추가할 수 있습니다. 데이터 흐름 엔진에서 오류 행을 처리하는 방법은 데이터 흐름 구성 요소에서 오류 출력 사용을 참조하십시오. 그러나 스크립트 구성 요소에서는 개발자가 직접 코드를 작성하여 추가 열을 적절한 오류 정보로 채워야 합니다. 자세한 내용은 스크립트 구성 요소의 오류 출력 시뮬레이션을 참조하십시오.
스크립트 변환 편집기의 입/출력 페이지에 대한 자세한 내용은 스크립트 변환 편집기(입/출력 페이지)를 참조하십시오.
변수 추가
스크립트에 사용하려는 값을 포함하는 기존 변수가 있는 경우 스크립트 변환 편집기의 스크립트 페이지에서 ReadOnlyVariables 및 ReadWriteVariables 속성 필드에 해당 변수를 추가할 수 있습니다.
속성 필드에 여러 변수를 입력하는 경우 변수 이름을 쉼표로 구분합니다. ReadOnlyVariables 및 ReadWriteVariables 속성 필드 옆의 줄임표(…) 단추를 클릭한 다음 변수 선택 대화 상자에서 변수를 선택하여 여러 개의 변수를 입력할 수도 있습니다.
스크립트 구성 요소에서 변수를 사용하는 방법은 스크립트 구성 요소에서 변수 사용을 참조하십시오.
스크립트 변환 편집기의 스크립트 페이지에 대한 자세한 내용은 스크립트 변환 편집기(스크립트 페이지)를 참조하십시오.
코드 디자인 모드에서 원본 구성 요소 스크립팅
구성 요소에 대한 메타데이터를 구성한 후에는 Microsoft VSTA(Visual Studio Tools for Applications) IDE를 열고 사용자 지정 스크립트를 코딩합니다. VSTA를 열려면 스크립트 변환 편집기의 스크립트 페이지에서 스크립트 편집을 클릭합니다. ScriptLanguage 속성에서 선택한 스크립트 언어에 따라 MicrosoftVisual Basic 2008 또는 MicrosoftVisual C# 2008 중 하나를 사용하여 스크립트를 작성할 수 있습니다.
스크립트 구성 요소를 사용하여 만든 모든 종류의 구성 요소에 적용되는 자세한 정보는 스크립트 구성 요소 코딩 및 디버깅을 참조하십시오.
자동 생성 코드 이해
원본 구성 요소를 만들고 구성한 후 VSTA IDE를 열면 편집 가능한 ScriptMain 클래스가 코드 편집기에 나타납니다. 이 ScriptMain 클래스에서 사용자 지정 코드를 작성합니다.
ScriptMain 클래스에는 CreateNewOutputRows 메서드에 대한 스텁이 포함되어 있습니다. CreateNewOutputRows는 원본 구성 요소에서 가장 중요한 메서드입니다.
VSTA에서 프로젝트 탐색기 창을 열면 스크립트 구성 요소가 읽기 전용 BufferWrapper 및 ComponentWrapper 프로젝트 항목도 생성했음을 확인할 수 있습니다. ScriptMain 클래스는 ComponentWrapper 프로젝트 항목의 UserComponent 클래스에서 상속됩니다.
런타임에 데이터 흐름 엔진은 ScriptComponent 부모 클래스의 PrimeOutput 메서드를 재정의하는 UserComponent 클래스의 PrimeOutput 메서드를 호출합니다. 그러면 PrimeOutput 메서드는 다음 메서드를 호출합니다.
CreateNewOutputRows 메서드: 처음에는 비어 있는 출력 버퍼에 데이터 원본의 행을 추가하려면 ScriptMain에서 이 메서드를 재정의합니다.
FinishOutputs 메서드: 이 메서드는 기본적으로 비어 있습니다. 출력을 완료하는 데 필요한 처리를 수행하려면 ScriptMain에서 이 메서드를 재정의합니다.
전용 MarkOutputsAsFinished 메서드: 이 메서드는 ScriptBuffer 부모 클래스의 SetEndOfRowset 메서드를 호출하여 출력이 끝났음을 데이터 흐름 엔진에 알립니다. 따라서 개발자가 작성하는 코드에서 SetEndOfRowset을 명시적으로 호출할 필요가 없습니다.
사용자 지정 코드 작성
사용자 지정 원본 구성 요소 만들기를 마치기 위해 ScriptMain 클래스에서 사용할 수 있는 다음 메서드에서 스크립트를 작성할 수 있습니다.
AcquireConnections 메서드를 재정의하여 외부 데이터 원본에 연결합니다. 연결 관리자에서 연결 개체나 필요한 연결 정보를 추출합니다.
모든 원본 데이터를 동시에 로드할 수 있는 경우 PreExecute 메서드를 재정의하여 데이터를 로드합니다. 예를 들어 SQL Server 데이터베이스에 대한 ADO.NET 연결에 대해 SqlCommand를 실행하고 모든 원본 데이터를 동시에 SqlDataReader로 로드할 수 있습니다. 텍스트 파일을 읽는 경우와 같이 원본 데이터를 한 번에 한 행씩 로드해야 하는 경우에는 CreateNewOutputRows에서 행을 반복할 때 데이터를 로드할 수 있습니다.
재정의된 CreateNewOutputRows 메서드를 사용하여 빈 출력 버퍼에 새 행을 추가하고 새 출력 행의 각 열 값을 채웁니다. 각 출력 버퍼의 AddRow 메서드를 사용하여 비어 있는 새 행을 추가한 다음 각 열의 값을 설정합니다. 일반적으로는 외부 원본에서 로드된 열의 값을 복사합니다.
PostExecute 메서드를 재정의하여 데이터 처리를 마칩니다. 예를 들어 데이터를 로드하는 데 사용한 SqlDataReader를 닫을 수 있습니다.
필요한 경우 ReleaseConnections 메서드를 재정의하여 외부 데이터 원본과의 연결을 끊습니다.
예
다음 예에서는 ScriptMain 클래스에서 원본 구성 요소를 만드는 데 필요한 사용자 지정 코드를 보여 줍니다.
[!참고]
이 예에서는 AdventureWorks 예제 데이터베이스의 Person.Address 테이블을 사용하고 이 테이블의 첫 번째 열인 intAddressID와 네 번째 열인 nvarchar(30)City를 데이터 흐름을 통해 전달합니다. 이 섹션의 원본, 변환 및 대상 예제에는 동일한 데이터가 사용됩니다. 각 예에 대해 필수 구성 요소 및 가정도 설명되어 있습니다.
ADO.NET 원본 예
이 예에서는 기존 ADO.NET 연결 관리자를 사용하여 SQL Server 테이블의 데이터를 데이터 흐름으로 로드하는 원본 구성 요소를 보여 줍니다.
이 예제 코드를 실행하려면 다음과 같이 패키지와 구성 요소를 구성해야 합니다.
SqlClient 공급자를 사용하여 AdventureWorks 데이터베이스에 연결하는 ADO.NET 연결 관리자를 만듭니다.
데이터 흐름 디자이너 화면에 새 스크립트 구성 요소를 추가하고 이 구성 요소를 원본으로 구성합니다.
스크립트 변환 편집기를 엽니다. 입/출력 페이지에서 기본 출력의 이름을 MyAddressOutput과 같이 보다 알기 쉬운 이름으로 바꾼 다음 AddressID와 City라는 두 개의 출력 열을 추가하고 구성합니다.
연결 관리자 페이지에서 ADO.NET 연결 관리자를 추가하거나 만들고 해당 이름을 MyADONETConnection과 같은 이름으로 지정합니다.
스크립트 페이지에서 스크립트 편집을 클릭하고 다음과 같이 스크립트를 입력합니다. 그런 다음 스크립트 개발 환경 및 스크립트 변환 편집기를 닫습니다.
SQL Server 대상이나 스크립트 구성 요소를 사용하여 대상 만들기에서 보여 준 예제 대상 구성 요소와 같이 AddressID 및 City 열을 필요로 하는 대상 구성 요소를 만들고 구성합니다. 그런 다음 원본 구성 요소를 대상에 연결합니다. 변환하지 않고 원본을 대상에 직접 연결할 수 있습니다. AdventureWorks 데이터베이스에서 다음 Transact-SQL 명령을 실행하여 대상 테이블을 만들 수 있습니다.
CREATE TABLE [Person].[Address2]( [AddressID] [int] NOT NULL, [City] [nvarchar](30) NOT NULL )
예제를 실행합니다.
Imports System.Data.SqlClient ... Public Class ScriptMain Inherits UserComponent Dim connMgr As IDTSConnectionManager100 Dim sqlConn As SqlConnection Dim sqlReader As SqlDataReader Public Overrides Sub AcquireConnections(ByVal Transaction As Object) connMgr = Me.Connections.MyADONETConnection sqlConn = CType(connMgr.AcquireConnection(Nothing), SqlConnection) End Sub Public Overrides Sub PreExecute() Dim cmd As New SqlCommand("SELECT AddressID, City, StateProvinceID FROM Person.Address", sqlConn) sqlReader = cmd.ExecuteReader End Sub Public Overrides Sub CreateNewOutputRows() Do While sqlReader.Read With MyAddressOutputBuffer .AddRow() .AddressID = sqlReader.GetInt32(0) .City = sqlReader.GetString(1) End With Loop End Sub Public Overrides Sub PostExecute() sqlReader.Close() End Sub Public Overrides Sub ReleaseConnections() connMgr.ReleaseConnection(sqlConn) End Sub End Class
using System.Data.SqlClient; public class ScriptMain: UserComponent { IDTSConnectionManager100 connMgr; SqlConnection sqlConn; SqlDataReader sqlReader; public override void AcquireConnections(object Transaction) { connMgr = this.Connections.MyADONETConnectionManager; sqlConn = (SqlConnection)connMgr.AcquireConnection(null); } public override void PreExecute() { SqlCommand cmd = new SqlCommand("SELECT AddressID, City, StateProvinceID FROM Person.Address", sqlConn); sqlReader = cmd.ExecuteReader(); } public override void CreateNewOutputRows() { while (sqlReader.Read()) { { MyAddressOutputBuffer.AddRow(); MyAddressOutputBuffer.AddressID = sqlReader.GetInt32(0); MyAddressOutputBuffer.City = sqlReader.GetString(1); } } } public override void PostExecute() { sqlReader.Close(); } public override void ReleaseConnections() { connMgr.ReleaseConnection(sqlConn); } }
플랫 파일 원본 예
이 예에서는 기존 플랫 파일 연결 관리자를 사용하여 플랫 파일의 데이터를 데이터 흐름으로 로드하는 원본 구성 요소를 보여 줍니다. 플랫 파일 원본 데이터는 SQL Server에서 데이터를 내보내는 방법으로 만듭니다.
이 예제 코드를 실행하려면 다음과 같이 패키지와 구성 요소를 구성해야 합니다.
SQL Server 가져오기 및 내보내기 마법사를 사용하여 AdventureWorks 예제 데이터베이스의 Person.Address 테이블을 쉼표로 구분된 플랫 파일로 내보냅니다. 이 예제에서는 파일 이름으로 ExportedAddresses.txt를 사용합니다.
내보낸 데이터 파일에 연결하는 플랫 파일 연결 관리자를 만듭니다.
데이터 흐름 디자이너 화면에 새 스크립트 구성 요소를 추가하고 이 구성 요소를 원본으로 구성합니다.
스크립트 변환 편집기를 엽니다. 입/출력 페이지에서 기본 출력의 이름을 MyAddressOutput과 같이 보다 알기 쉬운 이름으로 바꿉니다. AddressID 및 City라는 두 개의 출력 열을 추가하고 구성합니다.
연결 관리자 페이지에서 MyFlatFileSrcConnectionManager와 같이 알기 쉬운 이름을 사용하여 플랫 파일 연결 관리자를 추가하거나 만듭니다.
스크립트 페이지에서 스크립트 편집을 클릭하고 다음과 같이 스크립트를 입력합니다. 그런 다음 스크립트 개발 환경 및 스크립트 변환 편집기를 닫습니다.
SQL Server 대상이나 스크립트 구성 요소를 사용하여 대상 만들기에서 보여 준 예제 대상 구성 요소와 같은 대상 구성 요소를 만들고 구성합니다. 그런 다음 원본 구성 요소를 대상에 연결합니다. 변환하지 않고 원본을 대상에 직접 연결할 수 있습니다. AdventureWorks 데이터베이스에서 다음 Transact-SQL 명령을 실행하여 대상 테이블을 만들 수 있습니다.
CREATE TABLE [Person].[Address2]( [AddressID] [int] NOT NULL, [City] [nvarchar](30) NOT NULL )
예제를 실행합니다.
Imports System.IO ... Public Class ScriptMain Inherits UserComponent Private textReader As StreamReader Private exportedAddressFile As String Public Overrides Sub AcquireConnections(ByVal Transaction As Object) Dim connMgr As IDTSConnectionManager100 = _ Me.Connections.MyFlatFileSrcConnectionManager exportedAddressFile = _ CType(connMgr.AcquireConnection(Nothing), String) End Sub Public Overrides Sub PreExecute() MyBase.PreExecute() textReader = New StreamReader(exportedAddressFile) End Sub Public Overrides Sub CreateNewOutputRows() Dim nextLine As String Dim columns As String() Dim delimiters As Char() delimiters = ",".ToCharArray nextLine = textReader.ReadLine Do While nextLine IsNot Nothing columns = nextLine.Split(delimiters) With MyAddressOutputBuffer .AddRow() .AddressID = columns(0) .City = columns(3) End With nextLine = textReader.ReadLine Loop End Sub Public Overrides Sub PostExecute() MyBase.PostExecute() textReader.Close() End Sub End Class
using System.IO; public class ScriptMain: UserComponent { private StreamReader textReader; private string exportedAddressFile; public override void AcquireConnections(object Transaction) { IDTSConnectionManager100 connMgr = this.Connections.MyFlatFileSrcConnectionManager; exportedAddressFile = (string)connMgr.AcquireConnection(null); } public override void PreExecute() { base.PreExecute(); textReader = new StreamReader(exportedAddressFile); } public override void CreateNewOutputRows() { string nextLine; string[] columns; char[] delimiters; delimiters = ",".ToCharArray(); nextLine = textReader.ReadLine(); while (nextLine != null) { columns = nextLine.Split(delimiters); { MyAddressOutputBuffer.AddRow(); MyAddressOutputBuffer.AddressID = columns[0]; MyAddressOutputBuffer.City = columns[3]; } nextLine = textReader.ReadLine(); } } public override void PostExecute() { base.PostExecute(); textReader.Close(); } }
|