Создание источника с помощью компонента скрипта
Компонент источника в потоке данных пакета служб Службы Integration Services можно использовать для загрузки данных из источника данных для передачи в нижележащие преобразования и назначения. Обычно подключение к источнику данных осуществляется через существующий диспетчер соединений.
Общие сведения о компоненте скрипта см. в разделе Расширение потока данных с помощью компонента скрипта.
Компонент скрипта и формируемый им код инфраструктуры значительно упрощают процесс создания пользовательских компонентов потока данных. Однако, чтобы понять работу этого компонента скрипта, может потребоваться ознакомиться с шагами, связанными с разработкой пользовательского компонента потока данных. См. раздел Разработка пользовательского компонента потока данных, особенно подраздел Разработка пользовательского компонента источника.
Приступая к работе с компонентом источника
При добавлении компонента скрипта на панель «Поток данных» конструктора служб Службы SSIS открывается диалоговое окно Выбор типа компонента скрипта с приглашением выбрать скрипт источника, назначения или преобразования. В этом диалоговом окне выберите скрипт Источник.
Настройка компонента источника в режиме конструктора метаданных
После выбора для создания компонента источника необходимо настроить этот компонент с помощью окна Редактор преобразования «Скрипт». Дополнительные сведения см. в разделе Настройка компонента скрипта в редакторе компонента скрипта.
Компонент источника потока данных не имеет входов и поддерживает один или несколько выходов. Настройка выходов для компонента представляет собой один из шагов, который должен быть выполнен в режиме конструктора метаданных с помощью окна Редактор преобразования «Скрипт», до начала написания пользовательского скрипта.
Можно также указать язык скрипта, задавая свойство ScriptLanguage на странице Скрипт окна Редактор преобразования «Скрипт».
![]() |
---|
Чтобы задать применяемый по умолчанию язык скрипта для компонентов скриптов и задач «Скрипт», используйте параметр Язык скрипта на странице Общие диалогового окна Параметры. Дополнительные сведения см. в разделе Страница «Общие». |
Добавление диспетчеров соединений
Как правило, в компоненте источника используется существующий диспетчер соединений для подключения к источнику данных, из которого загружаются данные в поток данных. На странице Диспетчеры соединений в редакторе преобразования «Скрипт» нажмите кнопку Добавить, чтобы добавить нужный диспетчер соединений.
Но диспетчер соединений представляет собой всего лишь удобный модуль, который инкапсулирует и хранит информацию, необходимую для подключения к источнику данных конкретного типа. Чтобы загрузить или сохранить конкретные данные, необходимо написать собственный пользовательский код, а также, возможно, открыть и закрыть соединение с источником данных.
Общие сведения об использовании диспетчеров соединений в компоненте скрипта см. в разделе Соединение с источниками данных в компоненте скрипта.
Дополнительные сведения о странице Диспетчеры соединений редактора преобразования «Скрипт» см. в разделе Редактор преобразования «Скрипт» (страница «Диспетчеры соединений»).
Настройка выходов и выходных столбцов
Компонент источника не имеет входов и поддерживает один или несколько выходов. На странице Входы и выходы окна Редактор преобразования «Скрипт» по умолчанию был создан один выход, но не созданы какие-либо выходные столбцы. На этой странице редактора может понадобиться настроить следующие элементы.
Необходимо вручную добавить и настроить выходные столбцы для каждого выхода. Выберите папку Выходные столбцы для каждого выхода, а затем используйте кнопки Добавить столбец и Удалить столбец, чтобы управлять выходными столбцами для каждого выхода компонента источника. В дальнейшем можно будет ссылаться на выходные столбцы в скрипте по именам, присвоенным здесь, используя свойства типизированного метода доступа, созданные в автоматически сформированном коде.
Может потребоваться создать один или несколько дополнительных выводов, таких как эмулируемый вывод ошибок для строк, содержащих непредвиденные значения. Используйте кнопки Добавить выход и Удалить выход для управления выходами компонента источника. Все входные строки направляются во все доступные выходы, если только не задано идентичное ненулевое значение для свойства ExclusionGroup тех выходов, куда планируется направить каждую строку. Конкретное целочисленное значение, выбранное для идентификации группы ExclusionGroup, не имеет значения.
Примечание
Также можно использовать ненулевое значение для свойства ExclusionGroup с единственным выходом, если не нужно выводить все строки. Но в этом случае необходимо явно вызывать метод DirectRowTo<outputbuffer> для каждой строки, которую следует отправить на выход.
Может потребоваться присвоить выходам понятные имена. В дальнейшем можно будет ссылаться на выходы по их именам в скрипте, используя свойства типизированного метода доступа, созданные в автоматически сформированном коде.
Обычно несколько выходов в одной и той же группе ExclusionGroup имеют одинаковые выходные столбцы. Однако, если создается моделируемый вывод ошибок, может потребоваться добавить дополнительные столбцы для хранения сведений об ошибках. Сведения об обработке ошибочных строк в подсистеме обработки потока данных см. в разделе Использование выводов ошибок в компоненте потока данных. Тем не менее в компоненте скрипта необходимо написать собственный код, чтобы заполнить дополнительные столбцы соответствующими сведениями об ошибках. Дополнительные сведения см. в разделе Имитация вывода ошибок для компонента скрипта.
Дополнительные сведения о странице Входы и выходы редактора преобразования «Скрипт» см. в разделе Редактор преобразования «Скрипт» (страница «Входы и выходы»).
Добавление переменных
Если нужно использовать в скрипте значения существующих переменных, их можно добавить в поля свойств ReadOnlyVariables и ReadWriteVariables на странице Скрипт в редакторе преобразования «Скрипт».
При вводе нескольких переменных в поля свойств разделяйте имена переменных запятыми. Несколько переменных можно также ввести, нажимая кнопку с многоточием (...) рядом с полями свойств ReadOnlyVariables и ReadWriteVariables и выбирая переменные в диалоговом окне Выбор переменных.
Общие сведения об использовании переменных в компоненте скрипта см. в разделе Использование переменных в компоненте скрипта.
Дополнительные сведения о странице Скрипт редактора преобразования «Скрипт» см. в разделе Редактор преобразования «Скрипт» (страница «Скрипт»).
Сценарная поддержка компонента источника в режиме конструктора кода
После настройки метаданных для компонента откройте интегрированную среду разработки средств Microsoft Visual Studio для приложений (VSTA), чтобы разработать код пользовательского скрипта. Чтобы открыть среду VSTA, щелкните Изменить скрипт на странице Скрипт окна Редактор преобразования «Скрипт». Можно написать скрипт на языке Microsoft Visual Basic или Microsoft Visual C# в зависимости от того, какой язык скриптов выбран в качестве значения свойства ScriptLanguage.
Важные сведения, относящиеся ко всем типам компонентов, создаваемых с помощью компонента скрипта, см. в разделе Кодирование и отладка компонента скрипта.
Основные сведения об автоматически создаваемом коде
При открытии интегрированной среды разработки VSTA после создания и настройки компонента источника в редакторе кода появляется класс ScriptMain, который можно изменять. Пользовательский код пишется в классе ScriptMain.
Класс ScriptMain включает заглушку для метода CreateNewOutputRows. Метод CreateNewOutputRows является самым важным методом в компоненте источника.
Есть открыть окно Обозреватель объектов в средствах VSTA, можно увидеть, что для компонента скрипта были созданы элементы проекта BufferWrapper и ComponentWrapper, доступные только для чтения. Класс ScriptMain наследует класс UserComponent в элементе проекта ComponentWrapper.
Во время выполнения подсистема обработки потока данных вызывает метод PrimeOutput в классе UserComponent, который переопределяет метод PrimeOutput родительского класса ScriptComponent. Метод PrimeOutput в свою очередь вызывает следующие методы.
Метод CreateNewOutputRows, переопределяемый в классе ScriptMain для добавления строк от источника данных в выходные буферы (которые вначале пусты).
Метод FinishOutputs, который по умолчанию не содержит кода. Переопределите этот метод в классе ScriptMain, чтобы выполнять любую обработку, необходимую для завершения вывода.
Закрытый метод MarkOutputsAsFinished, который вызывает метод SetEndOfRowset родительского класса ScriptBuffer для уведомления подсистемы обработки потока данных о завершении вывода. Не следует вызывать метод SetEndOfRowset явно в собственном коде.
Написание пользовательского кода
Чтобы завершить создание пользовательского компонента источника, может потребоваться написать скрипт в следующих методах, доступных в классе ScriptMain.
Переопределите метод AcquireConnections для соединения с внешним источником данных. Извлеките из диспетчера соединений объект соединения или необходимые сведения о соединении.
Переопределите метод PreExecute для загрузки данных, если можно загрузить все исходные данные одновременно. Например, можно выполнить метод SqlCommand для соединения ADO.NET с базой данных SQL Server и загрузить все исходные данные одновременно в объект SqlDataReader. Если требуется загружать исходные данные в виде отдельных строк (например, при чтении текстового файла), то можно загружать данные в цикле по строкам в методе CreateNewOutputRows.
Используйте переопределенный метод CreateNewOutputRows, чтобы добавлять новые строки в пустые выходные буфера и заполнять новые строки вывода значениями каждого столбца. Используйте метод AddRow каждого выходного буфера, чтобы добавить новую пустую строку, а затем задавайте значения каждого столбца. Обычно значения копируются из столбцов, загруженных из внешнего источника.
Переопределите метод PostExecute, чтобы завершить обработку данных. Например, можно закрыть модуль SqlDataReader, который использовался для загрузки данных.
Переопределите метод ReleaseConnections, если необходимо разорвать соединение с внешним источником данных.
Примеры
В следующих примерах демонстрируется пользовательский код, который необходим в классе ScriptMain для создания компонента источника.
![]() |
---|
В этих примерах используется таблица Person.Address из образца базы данных AdventureWorks и в поток данных передаются ее первый и четвертый столбец — int AddressID и nvarchar(30) City. Эти же данные используются в образцах источника, преобразования и назначения, приведенных в этом разделе. Для каждого примера приведены необходимые дополнительные условия и принимаемые предположения. |
Пример источника ADO.NET
В этом примере демонстрируется компонент источника, в котором применяется существующий диспетчер соединений ADO.NET для загрузки данных из таблицы SQL Server в поток данных.
Для запуска этого образца кода необходимо настроить пакет и компонент следующим образом.
Создайте диспетчер соединений ADO.NET, использующий поставщик SqlClient для соединения с базой данных AdventureWorks.
Добавьте новый компонент скрипта в область конструктора потока данных и настройте его в качестве источника.
Откройте редактор преобразования «Скрипт». На странице Входы и выходы измените имя выхода по умолчанию на более описательное имя, такое как «ВыходАдреса», а также добавьте и настройте два выходных столбца, AddressID и City.
Примечание
Измените тип данных выходного столбца «City» на DT_WSTR.
На странице Диспетчеры соединений добавьте или создайте диспетчер соединений ADO.NET и присвойте ему описательное имя, такое как «СоединениеADONET».
На странице Скрипт нажмите кнопку Изменить скрипт и введите следующий скрипт. Затем закройте среду разработки скриптов и редактор преобразования «Скрипт».
Создайте и настройте компонент назначения, такой как назначение SQL Server, или образец компонента назначения, демонстрируемый в разделе Создание назначения с компонентом скрипта, который ожидает получение столбцов AddressID и City. Затем соедините компонент источника с назначением. (Можно соединить источник непосредственно с назначением, не выполняя никаких преобразований.) Можно создать целевую таблицу, выполнив следующую команду Transact-SQL в базе данных AdventureWorks:
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.MyADONETConnection; 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, чтобы экспортировать таблицу Person.Address из образца базы данных AdventureWorks в неструктурированный файл с разделителями запятыми. В этом образце используется файл с именем ExportedAddresses.txt.
Создайте диспетчер соединений с неструктурированными файлами, который подключается к экспортированному файлу данных.
Добавьте новый компонент скрипта в область конструктора потока данных и настройте его в качестве источника.
Откройте редактор преобразования «Скрипт». На странице Входы и выходы измените имя выхода по умолчанию на более описательное имя, такое как «ВыходАдреса». Добавьте и настройте два выходных столбца, AddressID и City.
На странице Диспетчеры соединений добавьте или создайте диспетчер соединений с неструктурированными файлами, используя описательное имя, такое как «ДиспетчерСоединенийСНеструктурированнымФайлом».
На странице Скрипт нажмите кнопку Изменить скрипт и введите следующий скрипт. Затем закройте среду разработки скриптов и редактор преобразования «Скрипт».
Создайте и настройте компонент назначения, такой как компонент назначения SQL Server, или образец компонента назначения, демонстрируемый в разделе Создание назначения с помощью компонента скрипта. Затем соедините компонент источника с назначением. (Можно соединить источник непосредственно с назначением, не выполняя никаких преобразований.) Можно создать целевую таблицу, выполнив следующую команду Transact-SQL в базе данных AdventureWorks:
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(); } }
|