以编程方式对输入进行 SSIS 脚本组件转换

Posted

技术标签:

【中文标题】以编程方式对输入进行 SSIS 脚本组件转换【英文标题】:SSIS Script Component Transformation of Input Programatically 【发布时间】:2020-11-30 08:18:31 【问题描述】:

我正在尝试使用 SSIS 脚本组件来转换我的输入数据,同时使用此博客中描述的方法: https://blog.theobald-software.com/2010/09/20/building-ssis-package-with-xtract-is-table-programmatically/

一切正常,我已经创建了源组件和目标组件,但我不知道如何使用代码的映射部分将我的输入列转换为所需的格式(如下所述)

//map the columns
IDTSPath100 path = dataFlowMainPipe.PathCollection.New();
path.AttachPathAndPropagateNotifications(DataSource.OutputCollection[0], OLEDBDestination.InputCollection[0]);
 
IDTSInput100 input = OLEDBDestination.InputCollection[0];
IDTSVirtualInput100 vInput = input.GetVirtualInput();
 
foreach (IDTSVirtualInputColumn100 vColumn in vInput.VirtualInputColumnCollection)

IDTSInputColumn100 vCol = InstanceDestination.SetUsageType(input.ID, vInput, vColumn.LineageID, DTSUsageType.UT_READWRITE);
InstanceDestination.MapInputColumn(input.ID, vCol.ID, input.ExternalMetadataColumnCollection[vColumn.Name].ID);

代码中有一个从输入到输出的 1:1 映射,但我需要将前 1..n-1 列从输入映射到输出中的 4 列,并将行数乘以 (n-1 )*input.CountRows,见下例

输入

Al  _1  _2  _3  _4  _5  _6  Value
a   A   5a  4a  2oa 5oa 4oa 10
b   B   5b  4b  2ob 5ob 4ob 20
c   C   5c  4c  2oc 5oc 4oc 30
d   D   5d  4d  2od 5od 4od 40
e   E   5e  4e  2oe 5oe 4oe 50
f   F   5f  4f  2of 5of 4of 60

输出

N   P   Key Value
Al  _1  a   A
Al  _1  b   B
Al  _1  c   C
Al  _1  d   D
Al  _1  e   E
Al  _1  f   F
Al  _2  a   5a
Al  _2  b   5b
Al  _2  c   5c
Al  _2  d   5d
Al  _2  e   5e
Al  _2  f   5f
Al  _3  a   4a
Al  …   …   …

我使用 Script 组件作为 Source,整个代码在 PreExecute 阶段执行。

非常感谢您的任何建议 BR 回复

【问题讨论】:

【参考方案1】:

您需要取消透视表

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication165

    class Program
    
        static void Main(string[] args)
        
            DataTable dt = new DataTable();
            dt.Columns.Add("A1", typeof(string));
            dt.Columns.Add("_1", typeof(string));
            dt.Columns.Add("_2", typeof(string));
            dt.Columns.Add("_3", typeof(string));
            dt.Columns.Add("_4", typeof(string));
            dt.Columns.Add("_5", typeof(string));
            dt.Columns.Add("_6", typeof(string));
            dt.Columns.Add("Value", typeof(string));

            dt.Rows.Add(new object[] "a","A", "5a", "4a", "2oa", "5oa", "4oa", "10");
            dt.Rows.Add(new object[] "b","B", "5b", "4b", "2ob", "5ob", "4ob", "20");
            dt.Rows.Add(new object[] "c","C", "5c", "4c", "2oc", "5oc", "4oc", "30");
            dt.Rows.Add(new object[] "d","D", "5d", "4d", "2od", "5od", "4od", "40");
            dt.Rows.Add(new object[] "e","E", "5e", "4e", "2oe", "5oe", "4oe", "50");
            dt.Rows.Add(new object[] "f","F", "5f", "4f", "2of", "5of", "4of", "60");

            DataTable dt1 = new DataTable();
            dt1.Columns.Add("N", typeof(string));
            dt1.Columns.Add("P", typeof(string));
            dt1.Columns.Add("Key", typeof(string));
            dt1.Columns.Add("Value", typeof(string));

            string[] headers = dt.Columns.Cast<DataColumn>().Select(x => x.ColumnName).ToArray();

            for (int col = 1; col < headers.Length; col++)
            
                foreach (DataRow row in dt.AsEnumerable())
                
                    dt1.Rows.Add(new object[]  "A1", headers[col], row[0], row[col] );
                
            
        
    

【讨论】:

jdweng,谢谢您的回答。这个解决方案真的很有帮助,但我的输入表不是静态的 - 这只是转换应该如何看起来的一个例子......这就是为什么我使用链接 - 博客中描述的方法。我必须使用组件元数据来导入输入列,并且我想使用MapInputColumn 方法进行此转换...请问您可以使用此方法重写您的解决方案吗?或者博客中提到的解决方案?非常感谢 为什么?一旦数据在 DataTable 中,您就可以从表中获取名称。使用 SQL 数据适配器时会自动创建默认映射。 是的,你是对的.. 所以我按照你写的那样创建了一个数据表,但是当我只有 InstanceSource.SetComponentProperty("TableName", this.SAPTableName); InstanceSource.SetComponentProperty("InternalXML", this.InternalXML); 这个数据流组件和设置源和目标的连接IDTSPath100 path = dataFlowMainPipe.PathCollection.New(); path.AttachPathAndPropagateNotifications(DataSource.OutputCollection[0], OLEDBDestination.InputCollection[0]);我不知道怎么用这个信息来填充DataTable 尝试以下:***.com/questions/25922107/…

以上是关于以编程方式对输入进行 SSIS 脚本组件转换的主要内容,如果未能解决你的问题,请参考以下文章

SSIS 脚本组件阻塞

转换的两个输入必须至少包含一个已排序的列,并且这些列必须具有匹配的元数据ssis

SSIS-导入Excel文件时记录行号

为SSIS编写简单的同步转换组件

SSIS 脚本组件 - 仅在调试模式下工作

SSIS 对数据排序