Создание назначения с помощью компонента скрипта

Область применения:среда выполнения интеграции SSIS SQL Server в Фабрика данных Azure

Компонент назначения используется в потоке данных пакета служб Integration Services для сохранения данных, полученных из вышестоящих источников и преобразований в источник данных. Обычно компонент назначения подключается к источнику данных через существующий диспетчер соединений.

Общие сведения о компоненте скрипта см. в разделе Расширение потока данных с помощью компонента скрипта.

Компонент скрипта и формируемый им код инфраструктуры значительно упрощают процесс создания пользовательских компонентов потока данных. Однако, чтобы понять, как работает компонент скрипта, вы можете ознакомиться с инструкциями по разработке компонентов пользовательского потока данных в разделе "Разработка пользовательского компонента потока данных " и особенно разработки пользовательского компонента назначения.

Начало работы с целевым компонентом

При добавлении компонента скрипта на вкладку Поток данных конструктора служб SSIS откроется диалоговое окно "Выбор типа компонента скрипта" и появится запрос на выбор сценария источника, назначения или преобразования. Выберите в этом диалоговом окне скрипт Назначение.

Затем подключите выходные данные преобразования к целевому компоненту в конструкторе служб SSIS. Для целей тестирования можно напрямую соединить источник с назначением без преобразований.

Настройка целевого компонента в режиме проектирования метаданных

Выбрав параметр создания компонента назначения, можно настроить его с помощью редактора преобразования "Скрипт". Дополнительные сведения см. в разделе Настройка компонента скрипта в редакторе компонента скрипта.

Чтобы выбрать язык скрипта, который использует назначение скрипта, задайте свойство ScriptLanguage на странице "Скрипт " диалогового окна редактора преобразования " Скрипт".

Примечание.

Чтобы установить язык скрипта по умолчанию для компонента скрипта, воспользуйтесь параметром Язык сценариев на странице Общие диалогового окна Параметры. Дополнительные сведения см. в разделе General Page.

Компонент назначения потока данных имеет один вход и ни одного выхода. Настройка входа компонента является одним из шагов, которые необходимо выполнить в режиме конструктора метаданных с использованием редактора преобразования "Скрипт", прежде чем приступать к написанию пользовательского скрипта.

Добавление диспетчеров подключений

Обычно компонент назначения через существующий диспетчер соединений подключается к источнику данных, куда сохраняет данные из потока данных. На странице Диспетчеры соединений в редакторе преобразования "Скрипт" нажмите кнопку Добавить, чтобы добавить нужный диспетчер соединений.

Однако диспетчер соединений — это просто удобная единица, которая инкапсулирует и сохраняет сведения, необходимые для подключения к источнику данных определенного типа. Для загрузки и сохранения данных, и, возможно, также для открытия и закрытия соединения с источником данных нужно разрабатывать собственный код.

Общие сведения об использовании диспетчеров соединений в компоненте скрипта см. в разделе Соединение с источниками данных в компоненте скрипта.

Дополнительные сведения о странице Диспетчеры подключенийредактора преобразования "Скрипт" см. в разделе Редактор преобразования "Скрипт" (страница "Диспетчеры подключений").

Настройка входных и входных столбцов

Компонент назначения имеет один вход и ни одного выхода.

На странице Входные столбцы в редакторе преобразования "Скрипт" список столбцов содержит доступные столбцы на выходе вышестоящего компонента в потоке данных. Выберите столбцы, которые нужно сохранить.

Дополнительные сведения о странице Входные столбцыредактора преобразования "Скрипт" см. в разделе Редактор преобразования "Скрипт" (страница "Входные столбцы").

Страница Входы и выходы диалогового окна Редактор преобразования "Скрипт" показывает один вход, который можно переименовать. Обратитесь к входным данным по имени в скрипте с помощью свойства доступа, созданного в автоматическом коде.

Дополнительные сведения о странице Входы и выходыредактора преобразования "Скрипт" см. в разделе Редактор преобразования "Скрипт" (страница "Входы и выходы").

Добавление переменных

Если нужно использовать в скрипте значения существующих переменных, их можно добавить в поля свойств ReadOnlyVariables и ReadWriteVariables на странице Скрипт в редакторе преобразования "Скрипт".

Если в поле свойства добавляются несколько переменных, их имена нужно разделять запятыми. Также можно выбрать несколько переменных, нажав кнопку с многоточием (), расположенную рядом с полями свойств ReadOnlyVariables и ReadWriteVariables, а затем выбрав переменные в диалоговом окне Выбор переменных.

Общие сведения об использовании переменных в компоненте скрипта см. в разделе Использование переменных в компоненте скрипта.

Дополнительные сведения о странице Скриптредактора преобразования "Скрипт" см. в разделе Редактор преобразования "Скрипт" (страница "Скрипт").

Скриптирование целевого компонента в режиме разработки кода

После настройки метаданных для компонента можно написать пользовательский скрипт. В редакторе преобразования скрипта на странице "Скрипт" нажмите кнопку "Изменить сценарий", чтобы открыть интегрированную среду разработки набор средств Microsoft Visual Studio Tools для работы с приложениями (VSTA), где можно добавить пользовательский скрипт. Используемый язык сценариев зависит от того, выбрали ли вы Microsoft Visual Basic или Microsoft Visual C# в качестве языка скрипта для свойства ScriptLanguage на странице скрипта .

Важные сведения, относящиеся ко всем типам компонентов, создаваемым с помощью компонента скрипта, см. в разделе Кодирование и отладка компонента скрипта.

Общие сведения об автоматическом создании кода

При открытии интегрированной среды разработки VSTA после создания и настройки целевого компонента в редакторе кода появится класс ScriptMain с заглушкой для метода ProcessInputRow . Класс ScriptMain — это то, где вы пишете пользовательский код, и ProcessInputRow является самым важным методом в целевом компоненте.

Если открыть окно Обозреватель проектов в VSTA, можно увидеть, что для компонента скрипта также были созданы элементы проекта BufferWrapper и ComponentWrapper, доступные только для чтения. Класс ScriptMain наследуется от класса UserComponent в элементе проекта ComponentWrapper.

Во время выполнения подсистема обработки потоков данных вызывает метод ProcessInput в классе UserComponent, переопределяющий метод ProcessInput родительского класса ScriptComponent. В свою очередь, метод ProcessInput проходит по строкам во входном буфере и вызывает для каждой строки метод ProcessInputRow.

Написание пользовательского кода

Чтобы завершить создание пользовательского компонента назначения, может потребоваться написать скрипт в следующих методах, доступных в классе ScriptMain .

  1. Переопределите метод AcquireConnections для соединения с внешним источником данных. Извлеките из диспетчера соединений объект соединения или необходимые сведения о соединении.

  2. Для подготовки к сохранению данных переопределите метод PreExecute. Например, может потребоваться создать и настроить SqlCommand и его параметры в этом методе.

  3. Используйте переопределенный метод ProcessInputRow для копирования всех строк ввода во внешний источник данных. Например, для назначения SQL Server можно скопировать значения столбцов в параметры SqlCommand и выполнить команду один раз для каждой строки. Для назначения "Неструктурированный файл" можно записать значения столбцов в объект StreamWriter, разделяя значения разделителем столбцов.

  4. Переопределите метод PostExecute для отключения от внешнего источника данных, если это требуется, и для выполнения всех прочих действий по очистке.

Примеры

В следующих примерах демонстрируется обязательный код в классе ScriptMain для создания целевого компонента.

Примечание.

В этих примерах используется таблица Person.Address из примера базы данных AdventureWorks. С помощью потока данных передаются ее первый и четвертый столбцы, intAddressID и nvarchar(30)City. Эти же данные используются в образцах источника, преобразования и назначения, приведенных в этом разделе. Для каждого примера приведены необходимые дополнительные условия и принимаемые предположения.

Пример назначения ADO.NET

В этом примере показан компонент назначения, использующий существующий диспетчер соединений ADO.NET для сохранения данных из потока данных в таблицу SQL Server.

Для запуска этого образца кода необходимо настроить пакет и компонент следующим образом.

  1. Создайте диспетчер соединений ADO.NET, который использует поставщика SqlClient для подключения к базе данных AdventureWorks .

  2. Создайте целевую таблицу, выполнив следующую команду Transact-SQL в базе данных AdventureWorks:

    CREATE TABLE [Person].[Address2]([AddressID] [int] NOT NULL,  
        [City] [nvarchar](30) NOT NULL)  
    
  3. Добавьте новый компонент скрипта в область конструктора потока данных и настройте его в качестве назначения.

  4. Подключите выходные данные вышестоящего источника или преобразования к целевому компоненту в конструкторе служб SSIS. (Вы можете подключить источник непосредственно к месту назначения без каких-либо преобразований.) Эти выходные данные должны предоставлять данные из таблицы Person.Address примера базы данных AdventureWorks, содержащей по крайней мере столбцы AddressID и City.

  5. Откройте редактор преобразования "Скрипт". На странице Входные столбцы выберите входные столбцы AddressID и City.

  6. На странице Входы и выходы измените имя входа на более описательное, например ВходАдреса.

  7. На странице диспетчер подключений добавьте или создайте диспетчер соединений ADO.NET с именем, например MyADONETConnectionManager.

  8. На странице Скрипт нажмите кнопку Изменить скрипт и введите следующий скрипт. Затем закройте среду разработки скрипта.

  9. Закройте редактор преобразования "Скрипт" и запустите образец.

Imports Microsoft.Data.SqlClient  
...  
Public Class ScriptMain  
    Inherits UserComponent  
  
    Dim connMgr As IDTSConnectionManager100  
    Dim sqlConn As SqlConnection  
    Dim sqlCmd As SqlCommand  
    Dim sqlParam As SqlParameter  
  
    Public Overrides Sub AcquireConnections(ByVal Transaction As Object)  
  
        connMgr = Me.Connections.MyADONETConnectionManager  
        sqlConn = CType(connMgr.AcquireConnection(Nothing), SqlConnection)  
  
    End Sub  
  
    Public Overrides Sub PreExecute()  
  
        sqlCmd = New SqlCommand("INSERT INTO Person.Address2(AddressID, City) " & _  
            "VALUES(@addressid, @city)", sqlConn)  
        sqlParam = New SqlParameter("@addressid", SqlDbType.Int)  
        sqlCmd.Parameters.Add(sqlParam)  
        sqlParam = New SqlParameter("@city", SqlDbType.NVarChar, 30)  
        sqlCmd.Parameters.Add(sqlParam)  
  
    End Sub  
  
    Public Overrides Sub MyAddressInput_ProcessInputRow(ByVal Row As MyAddressInputBuffer)  
        With sqlCmd  
            .Parameters("@addressid").Value = Row.AddressID  
            .Parameters("@city").Value = Row.City  
            .ExecuteNonQuery()  
        End With  
    End Sub  
  
    Public Overrides Sub ReleaseConnections()  
  
        connMgr.ReleaseConnection(sqlConn)  
  
    End Sub  
  
End Class  
using Microsoft.Data.SqlClient;  
public class ScriptMain:  
    UserComponent  
  
{  
    IDTSConnectionManager100 connMgr;  
    SqlConnection sqlConn;  
    SqlCommand sqlCmd;  
    SqlParameter sqlParam;  
  
    public override void AcquireConnections(object Transaction)  
    {  
  
        connMgr = this.Connections.MyADONETConnectionManager;  
        sqlConn = (SqlConnection)connMgr.AcquireConnection(null);  
  
    }  
  
    public override void PreExecute()  
    {  
  
        sqlCmd = new SqlCommand("INSERT INTO Person.Address2(AddressID, City) " +  
            "VALUES(@addressid, @city)", sqlConn);  
        sqlParam = new SqlParameter("@addressid", SqlDbType.Int);  
        sqlCmd.Parameters.Add(sqlParam);  
        sqlParam = new SqlParameter("@city", SqlDbType.NVarChar, 30);  
        sqlCmd.Parameters.Add(sqlParam);  
  
    }  
  
    public override void MyAddressInput_ProcessInputRow(MyAddressInputBuffer Row)  
    {  
        {  
            sqlCmd.Parameters["@addressid"].Value = Row.AddressID;  
            sqlCmd.Parameters["@city"].Value = Row.City;  
            sqlCmd.ExecuteNonQuery();  
        }  
    }  
  
    public override void ReleaseConnections()  
    {  
  
        connMgr.ReleaseConnection(sqlConn);  
  
    }  
  
}  

Пример назначения неструктурированного файла

В этом примере показан компонент назначения, который с помощью существующего диспетчера соединений с неструктурированными файлами сохраняет данные из потока данных в неструктурированный файл.

Для запуска этого образца кода необходимо настроить пакет и компонент следующим образом.

  1. Создайте диспетчер соединений с неструктурированными файлами, соединяющийся с целевым файлом. Файл не должен существовать; компонент назначения создает его. Настройте файл назначения как файл с разделителями-запятыми, содержащий столбцы AddressID и City.

  2. Добавьте новый компонент скрипта в область конструктора потока данных и настройте его в качестве назначения.

  3. Подключите выходные данные вышестоящего источника или преобразования к целевому компоненту в конструкторе служб SSIS. (Вы можете подключить источник непосредственно к месту назначения без каких-либо преобразований.) Эти выходные данные должны предоставлять данные из таблицы Person.Address примера базы данных AdventureWorks и содержать по крайней мере столбцы AddressID и City.

  4. Откройте редактор преобразования "Скрипт". На странице Входные столбцы выберите столбцы AddressID и City.

  5. На странице Входы и выходы измените имя входа на более описательное, например ВходАдреса.

  6. На странице Диспетчеры соединений добавьте или создайте диспетчер подключений к неструктурированным файлам с описательным именем, например MyFlatFileDestConnectionManager.

  7. На странице Скрипт нажмите кнопку Изменить скрипт и введите следующий скрипт. Затем закройте среду разработки скрипта.

  8. Закройте редактор преобразования "Скрипт" и запустите образец.

Imports System.IO  
...  
Public Class ScriptMain  
    Inherits UserComponent  
  
    Dim copiedAddressFile As String  
    Private textWriter As StreamWriter  
    Private columnDelimiter As String = ","  
  
    Public Overrides Sub AcquireConnections(ByVal Transaction As Object)  
  
        Dim connMgr As IDTSConnectionManager100 = _  
            Me.Connections.MyFlatFileDestConnectionManager  
        copiedAddressFile = CType(connMgr.AcquireConnection(Nothing), String)  
  
    End Sub  
  
    Public Overrides Sub PreExecute()  
  
        textWriter = New StreamWriter(copiedAddressFile, False)  
  
    End Sub  
  
    Public Overrides Sub MyAddressInput_ProcessInputRow(ByVal Row As MyAddressInputBuffer)  
  
        With textWriter  
            If Not Row.AddressID_IsNull Then  
                .Write(Row.AddressID)  
            End If  
            .Write(columnDelimiter)  
            If Not Row.City_IsNull Then  
                .Write(Row.City)  
            End If  
            .WriteLine()  
        End With  
  
    End Sub  
  
    Public Overrides Sub PostExecute()  
  
        textWriter.Close()  
  
    End Sub  
  
End Class  
using System.IO;  
public class ScriptMain:  
    UserComponent  
  
{  
    string copiedAddressFile;  
    private StreamWriter textWriter;  
    private string columnDelimiter = ",";  
  
    public override void AcquireConnections(object Transaction)  
    {  
  
        IDTSConnectionManager100 connMgr = this.Connections.MyFlatFileDestConnectionManager;  
        copiedAddressFile = (string) connMgr.AcquireConnection(null);  
  
    }  
  
    public override void PreExecute()  
    {  
  
        textWriter = new StreamWriter(copiedAddressFile, false);  
  
    }  
  
    public override void MyAddressInput_ProcessInputRow(MyAddressInputBuffer Row)  
    {  
  
        {  
            if (!Row.AddressID_IsNull)  
            {  
                textWriter.Write(Row.AddressID);  
            }  
            textWriter.Write(columnDelimiter);  
            if (!Row.City_IsNull)  
            {  
                textWriter.Write(Row.City);  
            }  
            textWriter.WriteLine();  
        }  
  
    }  
  
    public override void PostExecute()  
    {  
  
        textWriter.Close();  
  
    }  
  
}  

Создание источника с помощью компонента скрипта
Разработка пользовательского компонента назначения