Службы SSIS импорта данных, которые НЕ являются столбчатыми в SQL - PullRequest
0 голосов
/ 09 января 2020

Я довольно новичок в SSIS и мне нужна небольшая помощь для начала работы. У меня есть несколько отчетов, которые вышли из нашего мейнфрейма. Отчеты не в столбчатом формате. Запись даты находится вверху, тогда могут быть некоторые начальные данные, тогда может быть немного больше. Поэтому мне нужно прочитать в каждой строке, посмотреть, что читает текст, и выяснить, нужны ли мне данные или перейти к следующей строке.

Это ОЧЕНЬ грубый пример того, какой отчет я хочу импортировать в таблицу SQL.

DATE:  01/08/2020                   FACILITY NAME                             PAGE1

                 REVENUE USAGE                     FOR ACCOUNTING PERIOD 02
   ----TOTAL----  ----TOTAL----  ----OTHER----  ----INSURANCE----  ----INSURANCE2----  

SERVICE CODE - 123456789  DESCRIPTION:  WIDGETS
CURR                 2,077
 IP          0.0000      3     2,345     0.00       
                     143
 OP          0.0000      2     1,231     0.00

YTD                    5
   IP         0.0000
                       76 
   OP         0.0000   
etc . . . .. .
SERVICE CODE

После кода обслуживания данные начнут повторяться, как указано выше. Это основная идея отчета.

Я хочу получить Дата , а затем Сервисный код, описание, текущий объем IP, текущий IP-доллар, текущий объем OP, текущий OP-доллар, YTD IP-объем, YTD IP Доллар, с начала года ОП, доллар с начала года ОП . , затем повторите.

Просто чтобы прояснить, я никого не прошу сделать это для меня. Я хочу научиться делать это. Я посмотрел, как это сделать, но каждый пример, который я видел, рассказывает о том, как сделать это с помощью CSV, вкладки или файла Excel. у меня нет такого файла, поэтому я спрашивал, что мне нужно посмотреть. В настоящее время я использую Monarch для форматирования файла, но снова хочу узнать больше о SSIS, и это идеальный способ обучения. Попросить продавца повторить отчет - не вариант, и я хочу узнать, как это сделать. Спасибо, я просто хотел получить это там.

Любая помощь будет принята с благодарностью.
Роджер

1 Ответ

0 голосов
/ 10 января 2020

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

  1. Определение DataTable для хранения ваших данных.
  2. Используйте StreamReader для чтения вашего отчета.
  3. Обработайте это, используя комбинацию условных выражений, Строковые методы и синтаксический анализ чтобы извлечь соответствующие поля из соответствующей строки:
  4. Записать DataTable в базу данных, используя SqlBulkCopy

Следующее будет go внутри вашего метода Main в вашем задании сценария:

//Define a table to store your data 
var table = new DataTable
{
    Columns = 
    { 
        { "ServiceCode", typeof(string) }, 
        { "Description", typeof(string) }, 
        { "CurrentIPVolume", typeof(int) },
        { "CurrentIPDollar,", typeof(decimal) },
        { "CurrentOPVolume", typeof(int) },
        { "CurrentOPDollar", typeof(decimal) },
        { "YTDIPVolume", typeof(int) },
        { "YTDIPDollar,", typeof(decimal) },
        { "YTDOPVolume", typeof(int) },
        { "YTDOPDollar", typeof(decimal) } 
    }
};

var filePath = @"Your File Path";
using (var reader = new StreamReader(filePath))
{
    string line = null;
    DataRow row = null;

    // As YTD and Curr are identical, we will need a flag later to mark our position within the record
    bool ytdFlag= false; 

    //Loop through every line in the file 
    while ((line = reader.ReadLine()) != null)
    {
        //if the line is blank, move on to the next
        if (string.IsNullOrWhiteSpace(line)
            continue;

        // If the line starts with service code, then it marks the start of a new record
        if (line.StartsWith("SERVICE CODE"))
        {
            //If the current value for row is not null then this is
            //not the first record, so we need to add the previous 
            //record to the tale before continuing              
            if (row != null)
            {
                table.Rows.Add(row);
                ytdFlag= false; // New record, reset YTD flag
            }
            row = table.NewRow();

            //Split the line now based on known values:
            var tokens = line.Split(new string[] { "SERVICE CODE - ", "DESCRIPTION: "}, StringSplitOptions.None);

            row[0] = tokens[0];
            row[1] = tokens[1]; 
        }

        if (line.StartsWith("CURR"))
        {
            //Process the row --> "CURR                 2,077"
            //Not sure what 2,077 is, but this will parse it
            int i = 0;
            if (int.TryParse(line.Substring(4).Trim().Replace(",", ""), out i))
            {
                //Do something with your int
                Console.WriteLine(i);
            }

        }

        if (line.StartsWith(" IP"))
        {
            //Start at after IP then split the line into the 4 numbers
            var tokens = line.Substring(3).Split(new [] { " "}, StringSplitOptions.RemoveEmptyEntries);

            //If we have gone past the CURR record, then at to YTD Columns
            if (ytdFlag)
            {
                row[6] = int.Parse(tokens[1]);
                row[7] = decimal.Parse(tokens[1]);
            }
            //Otherwise we are still in the CURR section:
            else
            {
                row[2] = int.Parse(tokens[1]);
                row[3] = decimal.Parse(tokens[1]);
            }
        }
        if (line.StartsWith(" OP"))
        {
            //Start at after OP then split the line into the 4 numbers
            var tokens = line.Substring(3).Split(new [] { " "}, StringSplitOptions.RemoveEmptyEntries);

            //If we have gone past the CURR record, then at to YTD Columns
            if (ytdFlag)
            {
                row[8] = int.Parse(tokens[1]);
                row[9] = decimal.Parse(tokens[1]);
            }
            //Otherwise we are still in the CURR section:
            else
            {
                row[4] = int.Parse(tokens[1]);
                row[5] = decimal.Parse(tokens[1]);
            }

            //After we have processed an OP record, we must set the YTD Flag to true.
            //Doesn't matter if it is the YTD OP record, since the flag will be reset
            //By the next line that starts with SERVICE CODE anyway
            ytdFlag= true;
        }
    }
}

//Now that we have processed the file, we can write the data to a database
using (var sqlBulkCopy = new SqlBulkCopy("Your Connection String"))
{
    sqlBulkCopy.DestinationTableName = "dbo.YourTable";

    //If necessary add column mappings, but if your DataTable matches your database table
    //then this is not required

    sqlBulkCopy.WriteToServer(table);
}

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

Это определенно можно почистить и реорганизовать, но я постарался сделать как можно более ясным, что происходит, вместо того, чтобы пытаться написать самый эффективный код когда-либо. Он также должен (надеюсь) продемонстрировать, что это монументальная боль, и очень незначительный отчет меняет такие вещи, как лишний пробел, если «OP» сломает все это.

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

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