如何在 SSIS 中动态映射输入和输出列?
How to Map Input and Output Columns dynamically in SSIS?
我必须通过 SSIS 从 .dbf 文件上传数据到 SQL 服务器。
我的输出列是固定的,但输入列不是固定的,因为文件来自客户端,客户端可能已经按照自己的风格更新了数据。可能还有一些未使用的列,或者输入列名称可能与输出列不同。
我想到的一个想法是将文件输入列映射到 SQL 数据库 table 中的输出列,并仅使用文件 ID 行中存在的那些列。
但我不知道该怎么做。有什么想法吗?
Table 示例
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
如果您创建一个类似的 table,您可以在 2 种方法中使用它在 SSIS 包内动态映射列,或者您必须以编程方式构建整个包。在这个回答中,我将尝试给你一些关于如何做到这一点的见解。
(1) 使用别名构建源代码 SQL 命令
注意:只有当所有 .dbf 文件的列数相同但名称不同时,此方法才有效
在这种方法中,您将根据您创建的文件 ID 和映射 table 生成将用作源的 SQL 命令。您必须知道存储在变量中的文件 ID 和 .dbf 文件路径。例如:
假设Table名称为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
并且在“参数映射”选项卡中 select 包含要映射到参数的文件 ID 的变量 0
和包含 .dbf 文件名的变量(替代 table 名称)到参数 1
将结果集类型设置为 Single Row
并将结果集 0
存储在字符串类型的变量中,例如 @[User::SourceQuery]
ResultSet 值如下:
SELECT [CustCd] as [CustCode],[CNAME] as [CustName],[Address] as [CustAdd] FROM database1
在 OLEDB Source
select Table 访问模式到 SQL 来自变量的命令并使用 @[User::SourceQuery]
变量作为源。
(2) 使用脚本组件作为源
在这种方法中,您必须在数据流任务中使用脚本组件作为源:
首先,如果您不想硬编码,您需要通过变量将 .dbf 文件路径和 SQL 服务器连接传递到脚本组件。
在脚本编辑器中,您必须为在目标 table 中找到的每个列添加一个输出列,并将它们映射到目标。
在脚本中,您必须将 .dbf 文件读入数据table:
- C# Read from .DBF files into a datatable
- Load a DBF into a DataTable
将数据加载到一个数据table后,还要用您在SQL服务器中创建的映射Table中找到的数据填充另一个数据table。
在数据 table 列循环之后,将 .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();
}
循环遍历数据中的每一行后table并创建一个脚本输出行。
另外注意,在分配输出行时,必须检查列是否存在,可以先将所有列名添加到字符串列表中,然后使用它来检查,例如:
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
- Script Component as Source – SSIS
- SSIS – USING A SCRIPT COMPONENT AS A SOURCE
(3) 动态构建包
我认为除了您可以选择动态构建包之外,您没有其他方法可以用来实现这个目标,那么您应该选择:
(4) SchemaMapper:C# 模式映射class 库
最近我在 Git-Hub 上开始了一个新项目,这是一个使用 C# 开发的 class 库。您可以使用它将表格数据从 excel、word、powerpoint、text、csv、html、json 和 xml 导入 SQL 服务器 table 使用模式映射方法使用不同的模式定义。查看:
您可以关注此 Wiki 页面以获得分步指南:
我必须通过 SSIS 从 .dbf 文件上传数据到 SQL 服务器。 我的输出列是固定的,但输入列不是固定的,因为文件来自客户端,客户端可能已经按照自己的风格更新了数据。可能还有一些未使用的列,或者输入列名称可能与输出列不同。
我想到的一个想法是将文件输入列映射到 SQL 数据库 table 中的输出列,并仅使用文件 ID 行中存在的那些列。
但我不知道该怎么做。有什么想法吗?
Table 示例
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 |
如果您创建一个类似的 table,您可以在 2 种方法中使用它在 SSIS 包内动态映射列,或者您必须以编程方式构建整个包。在这个回答中,我将尝试给你一些关于如何做到这一点的见解。
(1) 使用别名构建源代码 SQL 命令
注意:只有当所有 .dbf 文件的列数相同但名称不同时,此方法才有效
在这种方法中,您将根据您创建的文件 ID 和映射 table 生成将用作源的 SQL 命令。您必须知道存储在变量中的文件 ID 和 .dbf 文件路径。例如:
假设Table名称为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
并且在“参数映射”选项卡中 select 包含要映射到参数的文件 ID 的变量 0
和包含 .dbf 文件名的变量(替代 table 名称)到参数 1
将结果集类型设置为 Single Row
并将结果集 0
存储在字符串类型的变量中,例如 @[User::SourceQuery]
ResultSet 值如下:
SELECT [CustCd] as [CustCode],[CNAME] as [CustName],[Address] as [CustAdd] FROM database1
在 OLEDB Source
select Table 访问模式到 SQL 来自变量的命令并使用 @[User::SourceQuery]
变量作为源。
(2) 使用脚本组件作为源
在这种方法中,您必须在数据流任务中使用脚本组件作为源:
首先,如果您不想硬编码,您需要通过变量将 .dbf 文件路径和 SQL 服务器连接传递到脚本组件。
在脚本编辑器中,您必须为在目标 table 中找到的每个列添加一个输出列,并将它们映射到目标。
在脚本中,您必须将 .dbf 文件读入数据table:
- C# Read from .DBF files into a datatable
- Load a DBF into a DataTable
将数据加载到一个数据table后,还要用您在SQL服务器中创建的映射Table中找到的数据填充另一个数据table。
在数据 table 列循环之后,将 .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();
}
循环遍历数据中的每一行后table并创建一个脚本输出行。
另外注意,在分配输出行时,必须检查列是否存在,可以先将所有列名添加到字符串列表中,然后使用它来检查,例如:
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
- Script Component as Source – SSIS
- SSIS – USING A SCRIPT COMPONENT AS A SOURCE
(3) 动态构建包
我认为除了您可以选择动态构建包之外,您没有其他方法可以用来实现这个目标,那么您应该选择:
(4) SchemaMapper:C# 模式映射class 库
最近我在 Git-Hub 上开始了一个新项目,这是一个使用 C# 开发的 class 库。您可以使用它将表格数据从 excel、word、powerpoint、text、csv、html、json 和 xml 导入 SQL 服务器 table 使用模式映射方法使用不同的模式定义。查看:
您可以关注此 Wiki 页面以获得分步指南: