如何在SSIS中动态映射输入和输出列?

Sha*_*dar 12 sql sql-server ssis etl ssis-2012

我必须通过SSIS从.dbf文件上传SQL Server中的数据。我的输出列是固定的,但输入列不是固定的,因为文件来自客户端,并且客户端可能会按照自己的样式更新数据。可能还有一些未使用的列,或者输入列的名称可能与输出列的名称不同。

我想到的一个主意是将SQL数据库表中的文件输入列与输出列进行映射,并仅使用文件ID行中存在的那些列。

但是我不知道该怎么做。您可以建议我这样做吗,否则您有任何想法吗?

表示例。

+--------+---------------+--------------+--------+ | FileID | InputColumn | OutputColumn | Active | +--------+---------------+--------------+--------+ | 1 | CustCd | CustCode | 1 | +--------+---------------+--------------+--------+ | 1 | CName | CustName | 1 | +--------+---------------+--------------+--------+ | 1 | Address | CustAdd | 1 | +--------+---------------+--------------+--------+ | 2 | Cust_Code | CustCode | 1 | +--------+---------------+--------------+--------+ | 2 | Customer Name | CustName | 1 | +--------+---------------+--------------+--------+ | 2 | Location | CustAdd | 1 | +--------+---------------+--------------+--------+

Had*_*adi 12

如果创建类似的表,则可以在2种方法中使用它来动态映射SSIS包内的列,或者必须以编程方式构建整个包。在此答案中,我将尝试为您提供一些有关如何执行此操作的见解。

(1)使用别名构建Source SQL命令

注意:仅当所有.dbf文件的列数相同但名称不同时,此方法才有效

通过这种方法,您将基于创建的FileID和Mapping表生成SQL命令,将其用作源。您必须知道FileID和.dbf文件路径存储在变量中。例如:

假设表名是inputoutputMapping

使用以下命令添加执行SQL任务:

DECLARE @strQuery as VARCHAR(4000)

SET @strQuery = 'SELECT '

SELECT @strQuery = @strQuery + '[' + InputColumn + '] as [' + OutputColumn + '],'
FROM inputoutputMapping
WHERE FileID = ?

SET @strQuery = SUBSTRING(@strQuery,1,LEN(@strQuery) - 1) + ' FROM ' + CAST(? as Varchar(500))

SELECT @strQuery
Run Code Online (Sandbox Code Playgroud)

然后在“参数映射”选项卡中,选择包含要映射到该参数的FileID的变量。 0的.dbf文件名(表名称的替代名称)的变量。1

将ResultSet类型设置为Single Row并存储ResultSet0 string类型的变量中,例如@[User::SourceQuery]

ResultSet值将如下所示:

SELECT [CustCd] as [CustCode],[CNAME] as [CustName],[Address] as [CustAdd] FROM database1
Run Code Online (Sandbox Code Playgroud)

在“ OLEDB Source从变量选择SQL命令的表访问模式”中,使用@[User::SourceQuery]变量作为源。


(2)使用脚本组件作为源

在这种方法中,您必须在数据流任务中使用脚本组件作为源:

首先,如果您不想对其进行硬编码,则需要通过变量将.dbf文件路径和SQL Server连接传递给脚本组件。

在脚本编辑器中,您必须 为在目标表中找到的每个列添加一个输出列,并将它们映射到destination

在脚本内部,必须将.dbf文件读入数据表:

将数据加载到数据表中之后,还用在SQL Server中创建的MappingTable中找到的数据填充另一个数据表。

之后,循环遍历datatable列,并将更改.ColumnName为相关的输出列,例如:

foreach (DataColumn col in myTable.Columns)
    {

    col.ColumnName = MappingTable.AsEnumerable().Where(x => x.FileID = 1 && x.InputColumn = col.ColumnName).Select(y => y.OutputColumn).First(); 

    }
Run Code Online (Sandbox Code Playgroud)

之后遍历数据表中的每一行并创建脚本输出行。

此外,请注意,在分配输出行时,必须检查该列是否存在,您可以首先将所有列名添加到字符串列表,然后使用它进行检查,例如:

var columnNames = myTable.Columns.Cast<DataColumn>()
                             .Select(x => x.ColumnName)
                             .ToList();  


foreach (DataColumn row in myTable.Rows){

if(columnNames.contains("CustCode"){

    OutputBuffer0.CustCode = row("CustCode");

}else{

    OutputBuffer0.CustCode_IsNull = True

}

//continue checking all other columns

}
Run Code Online (Sandbox Code Playgroud)

如果您需要有关使用脚本组件作为源的更多详细信息,请检查以下链接之一:


(3)动态构建软件包

我不认为可以使用其他方法来实现此目标,除非您可以选择动态构建程序包,然后再选择:


(4)SchemaMapper:C#模式映射类库

最近,我在Git-Hub上启动了一个新项目,该项目是使用C#开发的类库。您可以使用它使用架构映射方法将Excel,Word,PowerPoint,文本,CSV,HTML,JSON和xml的表格数据导入具有不同架构定义的SQL Server表中。在以下位置查看:

您可以按照以下Wiki页面获取逐步指南: