SSIS объединяет и объединяет несколько строк в отдельные строки без использования SQL - PullRequest
1 голос
/ 29 мая 2020

Я пытаюсь выполнить sh то, что довольно легко сделать в SQL, но, по-видимому, очень сложно сделать в SSIS без использования SQL. По сути, мне нужно консолидировать и объединить поле отношения «многие к одному».

Указанные объекты: [Элемент контракта] (многие) до (один) [Учетная запись]

Существует поле [ ari_productsummary ], которое содержит продукт, указанный в Пункт контракта объект. Мы хотим записать это значение в Учетную запись как [ ari_activecontractitems ]. Однако с Account может быть связано более одной записи Contract Item , и в этом случае мы хотим объединить эти значения. Мы также хотим, чтобы были объединены только отдельные значения (отдельные строки, уже решенные в моем потоке данных).

Это может быть выполнено путем записи во временную таблицу, а затем с помощью запроса или представления для получения итоговых результатов как следует. Я создал таблицу SQL под названием TESTTABLE , которая содержит [ ari_productsummary ] из объекта Contract Item вместе со ссылкой [ accountid ], чтобы отобразить его обратно в Учетную запись . Затем я написал следующий запрос в виде представления:

SELECT distinct accountid,
        (SELECT TT2.ari_productsummary + '; ' 
                FROM TESTTABLE TT2
                WHERE TT2.accountid = TT.accountid
                FOR XML PATH ('')
            ) AS 'ari_activecontractitems'
FROM TESTTABLE TT

Выполнение этого запроса предоставляет мне желаемые результаты, которые я затем могу использовать для импорта в сущность Account , как показано ниже. :

SSIS data flow, truncate temp sql table, write to sql table, pull from view and write to object

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

Mock-up of dataflow that I am trying to build out that doesn't require a SQL temp table/view

Есть ли у кого-нибудь решение, которое не требует временной SQL таблицы / просмотр / запрос, но целиком содержится в потоке данных?

Я использую VS 2017 и набор инструментов KingswaySoft Dynami c CRM 365 ETL для разработки своего решения / пакета.

Ответы [ 2 ]

1 голос
/ 29 мая 2020

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

ОБНОВЛЕНИЕ - 5 июня 2020 г. мы сделали компоненты доступными для publi c доступа по адресу https://www.kingswaysoft.com/products/ssis-productivity-pack/ в результате первой волны выпуска 2020 года. У нас есть два доступных компонента, которые служат этой цели. Компонент Composition принимает входные значения и преобразуется в составное значение в столбце SSIS. Компонент Decomposition делает противоположное: он принимает входное значение и разделяет его на несколько строк, используя либо разделение текста на основе разделителей, либо разделение массива XML / JSON.

1 голос
/ 29 мая 2020

Плевать здесь, потому что у меня нет Dynamics и у меня нет настраиваемых компонентов.

Поток данных 1 - Агрегация контрактов

Цель этого потока данных - реплицировать ваши logi c в элегантном запросе, который вы предоставили, и вставьте его в Диспетчер подключений к кешу (см. Примечания для 2008+ в конце)

Источник KingswaySoft Dynamics -> Задача сценария -> Преобразование кеша

Если вы хотите сохранить сортировку, сделайте это перед задачей скрипта. Реализация, которую я возьму с задачей сценария, заключается в том, что она полностью блокирует - то есть все строки должны прибыть, прежде чем она сможет отправить какую-либо. Такие задачи, как Merge Join, блокируются только частично , потому что требование отсортированных данных означает, что если у вас больше нет соответствия для текущего элемента, вы можете отправить его по конвейеру.

Задача сценария будет асинхронным преобразованием . У вас будет два выходных столбца: ваш ключ accountid и новый производный столбец ari_activecontractitems. Этот столбец, возможно, должен быть большим - вы будете знать свои данные лучше всего, но если это тип blob в Dynamics (> 4k unicode или> 8k ascii символов), вам нужно будет определить тип данных как DT_TEXT / DT_NTEXT

В качестве входных данных вы выберете accountid и ari_productsummary из вашего источника.

Код должен быть довольно простым. Мы собираемся накапливать входящие данные в словарь.

    //  member variable
    Dictionary<string, List<string>> accumulator;

Метод PreProcess, мы добавим его туда для инициализации нашей переменной

    // initialize in PreProcess method
    accumulator = new Dictionary<string, List<string>>();

В OnBufferRowSent (имя примерно)

    // simulate the inbound queue
    // row_id would be something like Rows.row_id
    if (!accumulator.ContainsKey(row_id))
    {
        // Create an empty dictionary for our list
        accumulator.Add(row_id, new List<string>());
    }

    // add it if we don't have it
    if (!accumulator[row_id].Contains(invoice))
    {
        accumulator[row_id].Add(invoice);
    }

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

    // This is how we shove data out the pipe
    foreach(var kvp in accumulator)
    {
        // approximately thus
        OutputBuffer1.AddRow();
        OutputBuffer1.row_id = kvp.Key;
        OutputBuffer1.ari_productsummary = string.Join("; ",  kvp.Value);

    }
...