Поделиться через


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

Область применения: среда выполнения интеграции 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 System.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 System.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();  
  
    }  
  
}  

См. также

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