【问题标题】:Parsing variable length record to table columns where specific column is dynamic in SSIS 2016将可变长度记录解析为表列,其中特定列在 SSIS 2016 中是动态的
【发布时间】:2019-07-18 18:23:19
【问题描述】:

我有一个包含 45 列税值的表格

| Tax1 | Tax2 | .......... | Tax 44 | Tax45 |

我读入了一个可变长度的位置记录,它可以包含 0 到 90 个值。记录的结构使得前 3 个字符是税码(值 001 - 045)​​,接下来的 7 个字符是税值:

Examples:
0010013.990140005.00

0040002.00

0150001.150320002.200410014.250420012.990430000.500440001.750450004.68

我想做的是,对于每条记录:

if ISNULL(record) or LEN(record) < 10 (3 characters for the code, 7 characters for the value)
    quit
else
    determine the amount of 10 character sections
    for each 10 character section
        taxCode = SUBSTRING(record, 1, 3)
        taxValue = SUBSTRING(record, 4, 10)

        table.Tax(taxCode).Value = taxValue (ex: using the first example record, column Tax1 will hold a value of 0013.99, Tax14 will be 0005.00)
    next section

    all other Tax[n] columns will have a value of 0.00
end if

有没有办法做到这一点,而不必创建 45 个变量,每个对应的列一个?

编辑: 我为缺乏明确性表示歉意。我从我们的 VMS 数据库中收到一个平面文件。该文件每个文件有多种记录类型(即:IT01、IT02、IT03、IT04、IT05、IT06、IT07)。每个记录类型都在其自己的行上。我把这个文件读入一个暂存表,其中的记录类型来自数据就行了。例如(这是我在问题中所指的记录类型):

IT06404034001005.000031013.000

这被加载到我的临时表中:

RecordType | RecordData                  |
------------------------------------------
IT06       | 404034001005.000031013.000

RecordData 字段可以进一步细分为:

ItemNumber | RecordData             |
-------------------------------------
404034     |  001005.000031013.000

【问题讨论】:

  • 我不确定您所说的“从变量读取”是什么意思。您是从平面文件中读取的吗?另外,我会在每一行上使用键、税种和税额垂直存储数据。
  • 我坚持我的初步评估。我会垂直处理它,并且没有 45 个税列(其中最多填写 9 个)。我会走 3 列宽。键、税码和税值。你可以很容易地将它们写在你的 foreach 循环中。
  • @KeithL 我已经编辑了我的问题,希望能解决您的评论。

标签: ssis script-task


【解决方案1】:

通过一些前期工作,我能够创建一个脚本任务来完全按照我的需要去做。

第 1 步:添加脚本组件。将其设置为转换

第 2 步:定义所有必要的输出列(漫长而乏味的任务,但它有效)

第3步:将以下代码放入脚本中

public override void Input0_ProcessInputRow(Input0Buffer Row){
    int sizeOfDataSegment = 11; // size of single record to be parsed (item number/next price)
    string recordDetail = Row.RecordDetail.ToString().Trim();
    string itemNumber = recordDetail.Substring(0, 6);
    //System.Windows.Forms.MessageBox.Show(String.Format("Record Detail: {0}", recordDetail));


    // we need a record for every item number, regardless if there are taxes or not
    Row.Company = Variables.strCompanyName;
    Row.ItemNumber = itemNumber;

    if (recordDetail.Length > 6){
        string taxData = recordDetail.Substring(6);

        if (string.IsNullOrEmpty(taxData)){
        }
        else{
            if (taxData.Length % sizeOfDataSegment == 0){
                int numberOfTaxes = taxData.Length / sizeOfDataSegment;
                //System.Windows.Forms.MessageBox.Show(String.Format("Number of taxe codes: {0}", numberOfTaxes.ToString()));
                int posTaxCode = 0;

                for (int x = 0; x < numberOfTaxes; x++){
                    string taxCode = taxData.Substring(posTaxCode, 3);
                    string taxValue = taxData.Substring(posTaxCode + 3, 8);
                    string outputColumnName = "TaxOut" + Convert.ToInt32(taxCode).ToString();

                    //System.Windows.Forms.MessageBox.Show(String.Format("TaxCode: {0}" + Environment.NewLine + "TaxValue: {1}", taxCode, taxValue));

                    //using taxCode value (ie: 001), find and set the value for the corresponding table column (ie: Tax1)
                    //foreach (System.Reflection.PropertyInfo dataColumn in Row.GetType().GetProperties()){
                    foreach (System.Reflection.PropertyInfo dataColumn in Row.GetType().GetProperties()){
                        if (dataColumn.Name == outputColumnName){
                            if (Convert.ToDecimal(taxValue) < 0){
                                // taxValue is a negative number, and therefore a percentage value
                                taxValue = (Convert.ToDecimal(taxValue) * -1).ToString() + "%";
                            }
                            else{
                                // taxValue is a positive number, and therefore a dollar value
                                taxValue = "$" + Convert.ToDecimal(taxValue).ToString();
                            }
                            dataColumn.SetValue(Row, taxValue);
                        }
                    }

                    posTaxCode += sizeOfDataSegment;
                }
            }
            else{
                System.Windows.Forms.MessageBox.Show(String.Format("Invalid record length({0}): {1}", taxData.Length, taxData));
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多