2014-10-28 3 views
0

У меня есть пакет SSIS, который использует условное разделение, чтобы получить какой-либо пакетный заголовок или трейлер в плоском файле с разделителями строк, взять первую строку и взять с нее код ошибки. Если код ошибки> 0, я записываю все обычные записи между заголовком партии и трейлером в отчет с этим кодом ошибки. В противном случае я выписываю только обычные записи с кодами ошибок. Вот что этот пример выглядит следующим образом:SSIS Обработка записей между заголовком и трейлером в плоском файле

//No batch level error 
00000BH 
00123NRNormalRecordData 
00000NRNormalRecordDataNoError 
00000BT 

Какой будет выглядеть так:

╔═══════════╦══════════════════╗ 
║ Error ║ Record Data ║ 
╠═══════════╬══════════════════╣ 
║  123 ║ NormalRecordData ║ 
╚═══════════╩══════════════════╝ 

И:

//Batch level error 
05555BH 
00000NRNormalRecordData 
00000NRNormalRecordData 
00000BT 

Какой будет выглядеть так:

╔═══════╦═════════════════════════╗ 
║ Error ║  Record Data  ║ 
╠═══════╬═════════════════════════╣ 
║ 5555 ║ NormalRecordData  ║ 
║  ║       ║ 
║ 5555 ║ NormalRecordData  ║ 
╚═══════╩═════════════════════════╝ 

Моя проблема с несколькими партиями, которые теперь завинчиваются (там используется только одна партия). Теперь я хочу сделать что-то вроде следующего

//Multi batch 
00000BH 
00123NRNormalRecordError 
00000NRNormalRecord 
00000BT 
00000BH 
00000SRSecondaryRecordType //want to ignore batches with no NR normal records 
00000BT 
05555BH 
00000NRNormalRecord 
00000NRNormalRecord 
00000BT 

Благодаря экономии ошибки уровня партии в переменный и проверить, если это нуль, когда я пишу записи из этого отчета будет неправильно выглядеть следующим образом:

╔═══════╦═════════════════════╗ 
║ Error ║ Record Data  ║ 
╠═══════╬═════════════════════╣ 
║ 5555 ║ NormalRecordError ║ 
║ 5555 ║ SecondaryRecordType ║ 
║ 5555 ║ NormalRecord  ║ 
║ 5555 ║ NormalRecord  ║ 
║ 5555 ║ NormalRecord  ║ 
╚═══════╩═════════════════════╝ 

Когда я хочу, чтобы это выглядело как:

╔═══════╦═══════════════════╗ 
║ Error ║ Record Data ║ 
╠═══════╬═══════════════════╣ 
║ 123 ║ NormalRecordError ║ 
║ 5555 ║ NormalRecord  ║ 
║ 5555 ║ NormalRecord  ║ 
╚═══════╩═══════════════════╝ 

Это происходит потому, что логика выглядит немного что-то вроде:

  • магазин ошибка уровня партии получить все нормальные записи с ошибкой, если не
  • ошибки уровня партии> 0, то получить их все записать все строки с партией
  • ошибкой уровня, если существует один или написать только нормальные строки, ошибка (этот случай будет работать, как задумано, потому что партия уровень переменной не заполняется)

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

Как бы вы справились с этим?

ответ

1

Вы можете использовать преобразование компонента сценария для анализа столбца и добавления строк на основе ваших условий. Ошибка заголовка может быть сохранена в переменной, объявленной вне метода Input0_ProcessInputRow.Вот шаги, которые я использовал:

  1. Я использовал данные выше, чтобы сделать один FlatFile столбец с данными имени столбца
  2. Добавить компонент сценария как преобразование
  3. Посмотри данные в качестве входного столбца
  4. Добавить новый выход под названием RecordOutput
  5. Добавить столбцы из положить: ошибка в междунар, Recorddata как строка

код:

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

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

    int error; 

    public override void Input0_ProcessInputRow(Input0Buffer Row) 
    { 
     //gets the row type 

     string rowType = Row.Data.Substring(5, 2); 

     //only sets the error variable if it is a header record 
     if (rowType == "BH") 
     { 
      error = Convert.ToInt32(Row.Data.Substring(0, 5)); 
     } 

     //Only adds a record for NR rows 
     if (rowType == "NR" && (error > 0 || Convert.ToInt32(Row.Data.Substring(0, 5)) > 0)) 
     { 
      RecordOutputBuffer.AddRow(); 
      if (error > 0) 
      { 
       RecordOutputBuffer.Error = error; 
      } 
      else 
      { 
       RecordOutputBuffer.Error = Convert.ToInt32(Row.Data.Substring(0, 5)); 
      } 
      RecordOutputBuffer.RecordData = Row.Data.Substring(7, Row.Data.Length - 7); 
     } 
    } 

} 

Вот что компонент выглядит следующим образом: enter image description here

Вот результаты: enter image description here