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

问题描述 投票:11回答:1

我必须通过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 | +--------+---------------+--------------+--------+

sql sql-server ssis ssis-2012 dbf
1个回答
11
投票

如果创建类似的表,则可以在2种方法中使用它来在SSIS包内动态映射列,或者必须以编程方式构建整个包。在这个答案中,我将尝试给你一些关于如何做到这一点的见解。

(1) Building Source SQL command with aliases

注意:此方法仅在所有.dbf文件具有相同列数但名称为不同的情况下才有效

在此方法中,您将生成SQL命令,该命令将基于您创建的FileID和Mapping表用作源。您必须知道FileID和存储在Variable中的.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

在参数映射选项卡中,选择包含要映射到参数0的FileID的变量,以及包含.dbf文件名的变量(替换为表名)到参数1的变量

将ResultSet类型设置为qazxsw poi并将结果集qazxsw poi存储在string类型的变量中作为示例Single Row

ResultSet值如下:

0

@[User::SourceQuery]中,从Variable选择Table Access Mode to SQL Command并使用SELECT [CustCd] as [CustCode],[CNAME] as [CustName],[Address] as [CustAdd] FROM database1 变量作为源。


(2) Using a Script Component as Source

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

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

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

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

  • OLEDB Source
  • @[User::SourceQuery]

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

在循环数据表列之后,将C# Read from .DBF files into a datatable更改为相关的输出列,例如:

Load a DBF into a 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(); }
  • 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 }
  • SSIS Script Component as Source
  • Creating a Source with the Script Component

(3) Building the package dynamically

我不认为有其他方法可以用来实现这个目标,除非你可以选择动态构建包,那么你应该采用:


(4) SchemaMapper: C# schema mapping class library

最近我在Git-Hub上开始了一个新项目,这是一个使用C#开发的类库。您可以使用它使用模式映射方法将表格数据从excel,word,powerpoint,text,csv,html,json和xml导入到具有不同模式定义的SQL服务器表中。看看:

您可以按照此Wiki页面获取分步指南:

© www.soinside.com 2019 - 2024. All rights reserved.