В задаче потока данных, как ограничить поток строк, используя значение из другого источника? - PullRequest
2 голосов
/ 15 апреля 2019

У меня есть лист Excel с множеством вкладок. Скажем, один называется wsMain, а другой - wsDate.

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

Теперь мне нужно обновить это преобразование, где я должен извлечь максимальную дату из рабочего листа wsDate и загружать данные только из wsMain, где дата меньше, чем соответствует максимальной дате в wsDate (это единственный доступный столбец) .

Итак, я понял, что мне нужно создать новый менеджер соединений Excel для чтения данных из wsDate, и я использовал преобразование Aggregate для получения максимальной даты.

Теперь вопрос в том, как использовать эту дату для ограничения строк, поступающих из wsMain?

Я понимаю по ссылке ниже, что вы можете сохранить значение в переменной, но что мне делать дальше ?: Набор результатов SSIS из потока данных в переменную

Я пытался использовать объединение слиянием, но не уверен, правильно ли я это делаю.

Вот как это выглядит сейчас:

https://imgur.com/dAXsGpm

Ответы [ 3 ]

1 голос
/ 15 апреля 2019

Сначала вы можете получить максимальное значение столбца wsDate, это используется в качестве фильтра, чтобы избежать внесения ненужных записей в поток данных, которые будут отброшены условным разделением. Обзор этого процесса ниже. Я также рекомендовал бы подтвердить типы данных для всех задействованных столбцов.

  • Создайте переменную SSIS DateTime и назовите это что-нибудь описательное, например MaxDate.

  • Создайте задание потока данных перед текущим с компонентом Excel Source. Используйте параметр команды SQL для режима доступа к данным и введите оператор SQL, чтобы получить максимальное значение столбца wsDate. В следующем примере ExcelSource - это имя листа, с которого вы тянете. Я также предложил подтвердить запрос кнопкой Preview в источнике Excel.

  • Добавить компонент сценария (не задачу) после источника Excel. Добавьте переменную MaxDate в поле ReadWriteVariables на главной странице компонента Script. На панели «Входы и выходы» добавьте столбец вывода из источника Excel в качестве столбца ввода с типом использования ReadOnly. Пример кода C # для этого ниже. Обратите внимание, что переменные могут быть записаны только в методе PostExecute. Метод Input0_ProcessInputRow вызывается один раз для каждой проходящей строки, однако в этом случае будет только одна строка. В следующем коде MaxExcelDate - это имя выходного столбца из источника Excel.

  • В компоненте «Источник Excel» в задаче «Поток данных», где записи импортируются из Excel, измените режим доступа к данным на команду SQL и введите инструкцию SQL, чтобы вернуть записи, дата которых меньше или равна максимальное значение wsDate. Это последний пример, и ? является заполнителем для параметра. После ввода этого SQL нажмите кнопку Parameters и выберите Parameter0 в поле «Параметры», переменную MaxDate для поля «Переменные» и направление ввода. Условное разделение можно затем удалить, поскольку эти записи теперь будут отфильтрованы.

Excel MAX wsDate SELECT:

SELECT MAX(wsDate) AS MaxExcelDate FROM ExcelSource

Компонент скрипта C #:

DateTime maxDate;
public override void PostExecute()
{
    base.PostExecute();
    Variables.MaxDate = maxDate;
}
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
    maxDate = Row.MaxExcelDate;
}

Команда Excel с фильтром даты:

SELECT 
    Column1,
    Column2,
    Column3
FROM ExcelSheet 
WHERE DateColumn <= ?
1 голос
/ 15 апреля 2019

Да, это возможно. В потоке данных вам нужно будет определить максимальную дату, которая у вас уже есть. Затем вам необходимо объединить два потока данных в столбце даты. Оттуда вы будете подавать его в УСЛОВНОЕ РАЗДЕЛЕНИЕ и делить там, где столбцы даты совпадают [т.е. ISNULL ()] и не совпадают [то есть ISNULL ()]. В вашем случае вы хотите только совпадения. Несоответствия будут проигнорированы.

Примечание: если вы используете INNER JOIN в MERGE JOIN, где есть только одна дата (т. Е. MaxDate), чтобы присоединиться, то это позаботится о фильтрации строк. Вам не понадобится УСЛОВНЫЕ РАЗДЕЛЕНИЯ.

Добро пожаловать в ETL.

Обновление

Реальная боль в том, что MERGE JOIN-ы SSIS выполняют соединения только для операций EQUAL, а не для операций LESS THAN и GREATER THAN. Вам нужно будет разделить потоки данных.

  1. Используйте компонент сценария для сканирования файла Excel на наличие максимальной даты и назначения этого значения переменной пакета в SSIS. Кроме того, вы можете создать таблицу дат в SQL Server, а затем использовать команду «Выполнить SQL» в службах SSIS, чтобы извлечь максимальную дату из таблицы и присвоить это значение переменной пакета
  2. Измените существующий поток данных, чтобы полностью удалить чтение файла даты в Excel. Затем добавьте преобразование DERIVED COLUMN и добавьте новый столбец, который сопоставлен с переменной пакета в SSIS, в которой хранится МАКСИМАЛЬНАЯ дата. Имя производного столбца можно назвать «MaxDate»
  3. Добавить преобразование условного разбиения со следующей логикой CONDITION: [AsOfDt] <= [MaxDate]
  4. Установить имя вывода для вставки записей

Примечание: CONDITIONAL SPLIT создает новый поток выходных данных с ограниченными / отфильтрованными строками. не создает новый столбец в существующем потоке данных. Думайте об этом как о переносе потока данных от модификации столбца к модификации строки. Только те строки, которые соответствуют условию, будут отправлены на вывод, который вы хотите. Я предполагаю, что вы хотите вставить только эти записи, поэтому я назвал это так. Вы можете выбрать любое соглашение о присвоении имен, которое вы предпочитаете

Примечание 2: Извините, что не сделал Обновление моим исходным ответом - раньше я не использовал преобразование AGGREGATE, поэтому я не знал, что оно ограничивает вывод строки, а не считывает значение в потоке данных и затем назначает его Переменная. Это было бы потрясающим преобразованием для Microsoft для добавления в SSIS. Похоже, что преобразования ROWCOUNT и SCRIPT COMPONENT - единственные, которые могут задавать значение переменной пакета в потоке данных.

1 голос
/ 15 апреля 2019

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

enter image description here

Вот пошаговое руководство, которому я следовал, чтобы написать переменную: https://www.proteanit.com/2008/12/11/ssis-writing-to-a-package-variable-in-a-dataflow/

...