Компонент сценария служб SSIS с несколькими входами - PullRequest
3 голосов
/ 22 апреля 2009

Я ищу способ создания компонента сценария в SSIS, который будет принимать несколько входных данных.

Мне нужно это, чтобы я мог сделать форму произвольного соединения.

Кажется действительно глупым, что скрипт может иметь несколько выходов, но только один вход, я уверен, что я что-то делаю не так.

Любая помощь?

Ответы [ 2 ]

1 голос
/ 22 апреля 2009

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

Имейте в виду, что вначале компонент сценария SSIS будет обрабатывать элементы строка за строкой, поэтому потребуется использовать специальный механизм объединения с использованием некоторых коллекций и захвата события, которое запускается после обработки всех строк.

Имейте в виду, что я предполагаю, что вы используете компонент потока в потоке данных, а не поток управления, и что я предполагаю, что вы используете SSIS 2005.

0 голосов
/ 02 апреля 2010

В настоящее время я экспериментирую с использованием переменных SSIS для передачи объектов синхронизации из одного компонента сценария в другой. Это довольно громоздко, но вы можете эффективно использовать несколько компонентов сценария для приема различных входных данных, а затем использовать классы System.Threading для синхронизации передача значений из одного компонента скрипта в другой.

Препятствие заключается в том, что каждый сценарий находится в своем собственном пространстве имен и не может использовать классы совместно с другими сценариями (если только вы не хотите компилировать и развертывать свою собственную сборку с помощью SSIS). В данный момент я передаю (через общую переменную) ссылку на объект [], содержащую ссылку на ManualResetEvent, SSIS PipelineBuffer и массив индексов столбцов конвейера.

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

Это функционально, хотя в настоящее время я ищу обходные пути к тому факту, что (казалось бы) SSIS дважды вызывает «ProcessInput» в течение срока службы компонента скрипта. Если у любого из гениев здесь, в SO, есть решение для этого, то я думаю, что у нас есть решение [clumsey], позволяющее использовать несколько входов для одного компонента скрипта.

Есть ли кто-нибудь?

---- РЕДАКТИРОВАТЬ ----

Я получил это и запустил - этот трюк состоит в том, чтобы использовать синхронизацию, чтобы многопоточный вызов ProcessInput не пытался совместно использовать й входной буфер несколько раз. Ниже приведен пример грубого кода того, как это работает:

Компонент скрипта 1: делится своими данными ...

using System;
using System.Collections;
using System.Threading;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using Microsoft.SqlServer.Dts.Pipeline;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{


    System.Collections.Generic.List<object> shared = null;
    System.Threading.ManualResetEvent sync;

    public override void ProcessInput(int InputID, PipelineBuffer Buffer)
    {
        lock (this)
        {
            if (InputID == 82)
            {
                if (shared == null)
                {
                    shared = new System.Collections.Generic.List<object>();
                    sync = new System.Threading.ManualResetEvent(false);
                    shared.Add(sync);
                    shared.Add(Buffer);
                    shared.Add(GetColumnIndexes(InputID));

                    IDTSVariables100 vars = null;

                    this.VariableDispenser.LockOneForWrite("Test", ref vars);

                    vars[0].Value = shared;
                    vars.Unlock();
                    sync.WaitOne();
                    System.Windows.Forms.MessageBox.Show("Done");
                }
            }
        }
    }
}

... затем компонент сценария 2 (который потребляет входные данные компонента сценария 1) ...

using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
    System.Threading.ManualResetEvent sync = null;
    InputXBuffer sharedBuffer = null;

    public override void Input0_ProcessInput(Input0Buffer Buffer)
    {
        lock (this)                 // Only 1 thread at a time
        {
            if (sharedBuffer == null)
            {
                object Test = null;
                while (Test == null)
                {
                    System.Threading.Thread.Sleep(100);
                    IDTSVariables100 vars = null;
                    this.VariableDispenser.LockOneForRead("Test", ref vars);
                    Test = vars[0].Value;
                    vars.Unlock();
                }

                var sharedList = Test as System.Collections.Generic.List<object>;

                if (sharedList != null)
                {
                    sync = sharedList[0] as System.Threading.ManualResetEvent;
                    var buffer = sharedList[1] as PipelineBuffer;
                    var bufferColumnIndexes = sharedList[2] as int[];
                    sharedBuffer = new InputXBuffer(buffer, bufferColumnIndexes);
                }
            }
       }

        while (sharedBuffer.NextRow())
        {
            // ... do stuff with Script Component 1's shared input here...
        }
        sync.Set();     // Signal script 1 that we're done
    }
}

Оба сценария имеют общую переменную для чтения / записи под названием «Test» - вы можете изменить имя переменной в соответствии со своими потребностями. К счастью, вышесказанное служит рабочей моделью для перехода на следующий уровень.

PS: - Если у вас есть время и энергия, то написание подходящего настраиваемого компонента SSIS действительно является подходом для сценариев с несколькими входами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...