Member 13093390 Ответов: 1

Преобразование компонент сценария служб SSIS


Всем Привет,

Я пытаюсь использовать источник плоских файлов в SSIS для заполнения некоторых таблиц базы данных. Я использовал Cinchoo NACHA Reader для обработки файла ACH. Частичные результаты этого файла приведены ниже.

-- Чоетл.нача.Состояние ChoNACHAFileHeaderRecord --
RecordTypeCode: FileHeader
Приоритетный код: 01
Немедленное назначение: 000000000
ImmediateOrigin: 000000000
Дата создания файла: 3.04.2017 12:00:00
FileCreationTime: 8/10/2017 7:47:00 AM
FileIDModifier: L
Размер записи: 94
Блокирующий фактор: 10
Формат-код: 1
ImmediateDestinationName: Название Отдела
ImmediateOriginName: Название Банка
ReferenceCode:

Затем я использую этот файл в качестве источника плоского файла в SSIS и использую двоеточие в качестве разделителя. Что дает две колонки. Один с именами столбцов и один со значениями.

Колонка 0 Колонка 1
RecordTypeCode FileHeader
PriorityCode 1
Немедленное назначение 00000000
ImmediateOrigin 00000000
FileCreationDate 2/1/2017
FileCreationTime 8/11/2017
FileIDModifier Л
RecordSize 94
BlockingFactor 10
Форматкод 1
ImmediateDestinationName Имя Назначения
ImmediateOriginName Исходное Имя
ReferenceCode

Отсюда я добавляю все свои желаемые выходные данные в компонент скрипта и применяю приведенный ниже код.

public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        string a = "-- ChoETL.NACHA.ChoNACHAFileHeaderRecord State --";
        string b = "-- ChoETL.NACHA.ChoNACHABatchHeaderRecord State --";
        string c = "-- ChoETL.NACHA.ChoNACHAEntryDetailRecord State -- ";
        string d = "-- ChoETL.NACHA.ChoNACHAAddendaRecord State --";
        string e = "-- ChoETL.NACHA.ChoNACHABatchControlRecord State --";
        string f = "-- ChoETL.NACHA.ChoNACHAFileControlRecord State --";
        
        
        if (Row.Column0 == a)
        {
            FileHeaderBuffer.AddRow();
        

        switch (Row.Column0.ToLower().Trim())
        {
            case "recordtypecode":
                FileHeaderBuffer.recordtypecode = Row.Column1.Trim();
                break;
            case "prioritycode":
                FileHeaderBuffer.prioritycode = Row.Column1.Trim();
                break;
            case "immediatedestination":
                FileHeaderBuffer.immediatedestination = Row.Column1.Trim();
                break;
            case "immediateorigin":
                FileHeaderBuffer.immediateorigin = Row.Column1.Trim();
                break;
            case "filecreationdate":
                FileHeaderBuffer.filecreationdate = Row.Column1.Trim();
                break;
            case "filecreationtime":
                FileHeaderBuffer.filecreationtime = Row.Column1.Trim();
                break;
            case "fileidmodifier":
                FileHeaderBuffer.fileidmodifier = Row.Column1.Trim();
                break;
            case "recordsize":
                FileHeaderBuffer.recordsize = Row.Column1.Trim();
                break;
            case "blockingfactor":
                FileHeaderBuffer.blockingfactor = Row.Column1.Trim();
                break;
            case "formatcode":
                FileHeaderBuffer.formatcode = Row.Column1.Trim();
                break;
            case "immediatedestinationname":
                FileHeaderBuffer.immediatedestinationname = Row.Column1.Trim();
                break;
            case "immediateoriginname":
                FileHeaderBuffer.immediateoriginname = Row.Column1.Trim();
                break;
            case "referencecode":
                FileHeaderBuffer.referencecode = Row.Column1.Trim();
                break;
        }
        
        {
            if (Row.Column0 == b)
            {
                BatchHeaderBuffer.AddRow();
            }

            switch (Row.Column0.ToLower().Trim())
            {
                case "recordtypecode":
                    BatchHeaderBuffer.recordtypecode = Row.Column1.Trim();
                    break;
                case "serviceclasscode":
                    BatchHeaderBuffer.serviceclasscode = Row.Column1.Trim();
                    break;
                case "companyname":
                    BatchHeaderBuffer.companyname = Row.Column1.Trim();
                    break;
                case "companydiscretionarydata":
                    BatchHeaderBuffer.companydiscretionarydata = Row.Column1.Trim();
                    break;
                case "companyid":
                    BatchHeaderBuffer.companyid = Row.Column1.Trim();
                    break;
                case "standardentryclasscode":
                    BatchHeaderBuffer.standardentryclasscode = Row.Column1.Trim();
                    break;
                case "companyentrydescription":
                    BatchHeaderBuffer.companyentrydescription = Row.Column1.Trim();
                    break;
                case "companydescriptivedate":
                    BatchHeaderBuffer.companydescriptivedate = Row.Column1.Trim();
                    break;
                case "effectiveentrydate":
                    BatchHeaderBuffer.effectiveentrydate = Row.Column1.Trim();
                    break;
                case "juliansettlementdate":
                    BatchHeaderBuffer.juliansettlementdate = Row.Column1.Trim();
                    break;
                case "originatorstatuscode":
                    BatchHeaderBuffer.originatorstatuscode = Row.Column1.Trim();
                    break;
                case "originatingdfiid":
                    BatchHeaderBuffer.originatingdfiid = Row.Column1.Trim();
                    break;
                case "batchnumber":
                    BatchHeaderBuffer.batchnumber = Row.Column1.Trim();
                    break;
            }
        
            {
                if (Row.Column0 == c)
                {
                    EntryDetailBuffer.AddRow();
                }

                switch (Row.Column0.ToLower().Trim())
                {
                    case "recordtypecode":
                        EntryDetailBuffer.recordtypecode = Row.Column1.Trim();
                        break;
                    case "transactioncode":
                        EntryDetailBuffer.transactioncode = Row.Column1.Trim();
                        break;
                    case "receivingdfiid":
                        EntryDetailBuffer.receivingdfiid = Row.Column1.Trim();
                        break;
                    case "checkdigit":
                        EntryDetailBuffer.checkdigit = Row.Column1.Trim();
                        break;
                    case "dfiaccountnumber":
                        EntryDetailBuffer.dfiaccountnumber = Row.Column1.Trim();
                        break;
                    case "amount":
                        EntryDetailBuffer.amount = Row.Column1.Trim();
                        break;
                    case "individualidnumber":
                        EntryDetailBuffer.individualidnumber = Row.Column1.Trim();
                        break;
                    case "individualname":
                        EntryDetailBuffer.individualname = Row.Column1.Trim();
                        break;
                    case "discretionarydata":
                        EntryDetailBuffer.discretionarydata = Row.Column1.Trim();
                        break;
                    case "addendarecordindicator":
                        EntryDetailBuffer.addendarecordindicator = Row.Column1.Trim();
                        break;
                    case "tracenumber":
                        EntryDetailBuffer.tracenumber = Row.Column1.Trim();
                        break;
            }
            
            {
                    if (Row.Column0 == d)
                    {
                        AddendaRecordBuffer.AddRow();
                    }

                    switch (Row.Column0.ToLower().Trim())
                    {
                        case "recordtypecode":
                            AddendaRecordBuffer.recordtypecode = Row.Column1.Trim();
                            break;
                        case "addendatypecode":
                            AddendaRecordBuffer.addendatypecode = Row.Column1.Trim();
                            break;
                        case "paymentrelatedinformation":
                            AddendaRecordBuffer.paymentrelatedinformation = Row.Column1.Trim();
                            break;
                        case "addendasequencenumber":
                            AddendaRecordBuffer.addendasequencenumber = Row.Column1.Trim();
                            break;
                        case "entrydetailsequencenumber":
                            AddendaRecordBuffer.entrydetailsequencenumber = Row.Column1.Trim();
                            break;
                    }
                    
                    {
                        if (Row.Column0 == e)
                        {
                            BatchControlBuffer.AddRow();
                        }

                        switch (Row.Column0.ToLower().Trim())
                        {
                            case "recordtypecode":
                                BatchControlBuffer.recordtypecode = Row.Column1.Trim();
                                break;
                            case "serviceclasscode":
                                BatchControlBuffer.serviceclasscode = Row.Column1.Trim();
                                break;
                            case "entryaddendacount":
                                BatchControlBuffer.entryaddendacount = Row.Column1.Trim();
                                break;
                            case "entryhash":
                                BatchControlBuffer.entryhash = Row.Column1.Trim();
                                break;
                            case "totaldebitentrydollaramount":
                                BatchControlBuffer.totaldebitentrydollaramount = Row.Column1.Trim();
                                break;
                            case "totalcreditentrydollaramount":
                                BatchControlBuffer.totalcreditentrydollaramount = Row.Column1.Trim();
                                break;
                            case "companyid":
                                BatchControlBuffer.companyid = Row.Column1.Trim();
                                break;
                            case "messageauthenticationcode":
                                BatchControlBuffer.messageauthenticationcode = Row.Column1.Trim();
                                break;
                            case "reserved":
                                BatchControlBuffer.reserved = Row.Column1.Trim();
                                break;
                            case "originatingdfiid":
                                BatchControlBuffer.originatingdfiid = Row.Column1.Trim();
                                break;
                            case "batchnumber":
                                BatchControlBuffer.batchnumber = Row.Column1.Trim();
                                break;
                        }
                        
                        {
                            if (Row.Column0 == f)
                            {
                                FileControlBuffer.AddRow();
                            }

                            switch (Row.Column0.ToLower().Trim())
                            {
                                case "recordtypecode":
                                    FileControlBuffer.recordtypecode = Row.Column1.ToUpper().Trim();
                                    break;
                                case "batchcount":
                                    FileControlBuffer.batchcount = Row.Column1.Trim();
                                    break;
                                case "blockcount":
                                    FileControlBuffer.blockcount = Row.Column1.Trim();
                                    break;
                                case "entryaddendacount":
                                    FileControlBuffer.entryaddendacount = Row.Column1.Trim();
                                    break;
                                case "entryhash":
                                    FileControlBuffer.entryhash = Row.Column1.Trim();
                                    break;
                                case "totaldebitentrydollaramount":
                                    FileControlBuffer.totaldebitentrydollaramount = Row.Column1.Trim();
                                    break;
                                case "totalcreditentrydollaramount":
                                    FileControlBuffer.totalcreditentrydollaramount = Row.Column1.Trim();
                                    break;
                                case "reserved":
                                    FileControlBuffer.reserved = Row.Column1.Trim();
                                    break;
                            }
                        }
                    }
                }
            }
        }
    }
    public override void Input0_ProcessInput(Input0Buffer Buffer)
    {
        while (Buffer.NextRow())
        {
            Input0_ProcessInputRow(Buffer);
        }

        if (Buffer.EndOfRowset())
        {
            FileHeaderBuffer.SetEndOfRowset();
            BatchHeaderBuffer.SetEndOfRowset();
            EntryDetailBuffer.SetEndOfRowset();
            BatchControlBuffer.SetEndOfRowset();
            FileControlBuffer.SetEndOfRowset();
        }
    }

    public override void CreateNewOutputRows()
    {
        BatchHeaderBuffer.AddRow();
        EntryDetailBuffer.AddRow();
        AddendaRecordBuffer.AddRow();
        BatchControlBuffer.AddRow();
        FileControlBuffer.AddRow();
    }

}


Я включил datareader из источника плоского файла в компонент скрипта, и все строки присутствуют. Когда строки проходят через выходные данные компонента скрипта в таблицы, либо таблицы заполняются одной строкой из нижней части файла, либо правильное количество строк вводится с нулевыми значениями. Я новичок в C#, поэтому я знаю, что делаю что-то не так, я просто не знаю, что это такое. Я полагаю, что это может иметь какое-то отношение к синтаксису моих операторов “if” или дублирующимся именам столбцов, которые существуют в файле. Любой совет будет очень признателен.

Что я уже пробовал:

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

Как использовать компонент скрипта в качестве асинхронного преобразования
http://www.rad.pasfu.com/index.php?/archives/19-How-to-use-Script-Component-as-Asynchronous-Transformation.html

Синтаксический анализ нестандартных форматов текстовых файлов с помощью компонента Script
https://technet.microsoft.com/en-us/library/ms345160(в=в SQL.110).aspx-файл

1 Ответов

Рейтинг:
12

CHill60

Будьте очень осторожны с тем, как вы отступаете свой код, и ошибки иногда будут выскакивать на вас.

Например, посмотрите на сегмент...

}
        
        {
            if (Row.Column0 == b)
            {
                BatchHeaderBuffer.AddRow();
            }

- То, что случайная открытая скобка { на линии сама по себе не нужна, но важно Row.Column0 никогда не может сравниться b потому что чтобы добраться до этой части кода Row.Column0 == a Проверьте это, отладив свой код - эта статья поможет вам начать работу Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]

Вы непоследовательны в своей структуре - если столбец == a вы добавляете строку, а затем заполняете ее в том же операторе. Но если it == b, вы только добавляете строку и пытаетесь заполнить ее вне блока оператора ... который просто перезапишет предыдущие значения, если столбец != b. И тем самым нависает ваша проблема, я считаю - попробуйте поставить закрывающую скобку в нужное место...
if (Row.Column0 == a)
{
    FileHeaderBuffer.AddRow();
}

Кроме того, гораздо легче следить за потоком вашего кода, если вы разбиваете материал на подпрограммы ... например все эти операторы switch могут быть извлечены в подпрограммы например
public override void UpdateFileHeader(string testString, string valueString)
{
	switch (testString)
	{
		case "recordtypecode":
			FileHeaderBuffer.recordtypecode = valueString;
			break;
...etc.
Ваш Input0_ProcessInputRow потом начинает походить...
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
    string a = "-- ChoETL.NACHA.ChoNACHAFileHeaderRecord State --".ToLower().Trim();
    string b = "-- ChoETL.NACHA.ChoNACHABatchHeaderRecord State --".ToLower().Trim();
    string c = "-- ChoETL.NACHA.ChoNACHAEntryDetailRecord State -- ".ToLower().Trim();
    string d = "-- ChoETL.NACHA.ChoNACHAAddendaRecord State --".ToLower().Trim();
    string e = "-- ChoETL.NACHA.ChoNACHABatchControlRecord State --".ToLower().Trim();
    string f = "-- ChoETL.NACHA.ChoNACHAFileControlRecord State --".ToLower().Trim();
    
    if (Row.Column0.ToLower().Trim() == a)
    {
        FileHeaderBuffer.AddRow();
    }

    UpdateFileHeader(Row.Column0.ToLower().Trim(), Row.Column1.Trim());
	
    if (Row.Column0 == b)
    {
	BatchHeaderBuffer.AddRow();
    }

    UpdateBatchHeader(Row.Column0.ToLower().Trim(), Row.Column1.Trim());
	
    if (Row.Column0 == c)
    {
        EntryDetailBuffer.AddRow();
    }

    UpdateEntryDetail(Row.Column0.ToLower().Trim(), Row.Column1.Trim());
    
    if (testString == d)
    {
        AddendaRecordBuffer.AddRow();
    }

    UpdateAddendaRecord(Row.Column0.ToLower().Trim(), Row.Column1.Trim());
        
...etc
Теперь становится совершенно ясно, что вы пытаетесь обновить каждый буфер для каждый строка в вашем файле. Вам нужно отслеживать, какой "раздел" файла вы обрабатываете, и только вызывать подходящий подпрограмма. Например (NB непроверенный)
const string a = "-- ChoETL.NACHA.ChoNACHAFileHeaderRecord State --";
const string b = "-- ChoETL.NACHA.ChoNACHABatchHeaderRecord State --";
const string c = "-- ChoETL.NACHA.ChoNACHAEntryDetailRecord State -- ";
const string d = "-- ChoETL.NACHA.ChoNACHAAddendaRecord State --";
const string e = "-- ChoETL.NACHA.ChoNACHABatchControlRecord State --";
const string f = "-- ChoETL.NACHA.ChoNACHAFileControlRecord State --";

public override void Input0_ProcessInputRow(Input0Buffer Row, out section)
{
switch(Row.Column0.ToLower().Trim())
{
    case a:
    FileHeaderBuffer.AddRow();
    section = 1;
    return;
    case b:
    BatchHeaderBuffer.AddRow();
    section = 2;
    return;
    case c:
    EntryDetailBuffer.AddRow();
    section = 3;
    return;
    case d:
    AddendaRecordBuffer.AddRow();
    section = 4;
    return;
    case e:
    BatchControlBuffer.AddRow();
    section = 5;
    return;
    case f:
    FileControlBuffer.AddRow();
    section = 6;
    return;
    default:
            string col0 = Row.Column0.ToLower().Trim();
            string col1 = Row.Column0.Trim();
    switch case (section)
    {
        case 1:
            UpdateFileHeader(col0,col1);
        break;
        case 2:
            UpdateBatchHeader(col0, col1);
        break;
        case 3:
        UpdateEntryDetail(col0,col1);
        break;
        case 4:
        UpdateAddendaRecord(col0,col1);
        break;
        case 5:
        UpdateBatchControl(col0,col1);
        break;
        case 6:
        UpdateFileControl(col0,col1);
        break;
    }
}
}