SSIS - 输出到平面文件的各种列数

SSIS - Various number of columns to output to flat file

我目前正在创建一个 SSIS,它将从数据库中收集数据并将其输出到单个以逗号分隔的平面文件。该文件将包含订单详细信息文件格式为

Order#1 details (51 columns)
Order#1 header  (62 columns)
Order#2 details (51 columns)
Order#2 header  (62 columns)
etc...

订单header有62列,订单详情有51列。我需要将其输出到一个平面文件,我 运行 遇到了一个问题,因为 SSIS 不处理不同的列。有人可以帮我吗,鉴于我的源是带有查询的 OLEDB 源,我如何创建脚本组件以输出到文件。

当前包如下所示:

  1. 获取所有订单的列表。将 orderid 作为变量传递。
  2. for循环容器遍历每个orderid,运行是一个数据任务流,获取订单的订单详情。 运行 获取订单的数据任务 header。 我只是 运行 正在解决将每一行输出到平面文件的问题。

如果有人能提供帮助,我们将不胜感激。我已经为此苦苦挣扎了一个星期 now.If 任何人都可以让我从脚本组件代码应该是什么样子开始,我将不胜感激。

我已经添加了到目前为止的内容: http://imgur.com/a/yTxfH

这是我的脚本的样子:

public void Main()
    {
        // TODO: Add your code here
        DataTable RecordType300 = new DataTable();
        DataTable RecordType210 = new DataTable();
        DataTable RecordType220 = new DataTable();
        DataTable RecordType200 = new DataTable();

        OleDbDataAdapter adapter = new OleDbDataAdapter();
        adapter.Fill(RecordType300, Dts.Variables["User:rec_type300"].Value);
        adapter.Fill(RecordType210, Dts.Variables["User::rec_type_210"].Value);
        adapter.Fill(RecordType220, Dts.Variables["User::rec_type_220"].Value);
        adapter.Fill(RecordType200, Dts.Variables["User::rec_type200"].Value);
        using (StreamWriter outfile = new StreamWriter("C:\myoutput.csv"))
        {
            for (var i = 0; i < RecordType300.Rows.Count; i++)
            {
                var detailFields = RecordType300.Rows[i].ItemArray.Select(field => field.ToString()).ToArray();
               // var poBillFields = RecordType210.Rows[i].ItemArray.Select(field => field.ToString()).ToArray();
              //  var poShipFields = RecordType220.Rows[i].ItemArray.Select(field => field.ToString()).ToArray();
             //   var poHeaderFields = RecordType200.Rows[i].ItemArray.Select(field => field.ToString()).ToArray();
                outfile.WriteLine(String.Join(",", detailFields));
              //  outfile.WriteLine(string.Join(",", poBillFields));
              //  outfile.WriteLine(string.Join(",", poShipFields));
              //  outfile.WriteLine(string.Join(",", poHeaderFields));
            }
        }

        Dts.TaskResult = (int)ScriptResults.Success;

    }

但每次我 运行 它都会出错。我在这里错过了什么吗?另外,我将如何在开始时只创建一个文件 1 次。这意味着每次这个包是 运行 时,它都会创建一个带有日期戳的文件并每次附加到它。下次打包 运行s 时,它将创建一个带有新日期戳的新文件,并根据订单号附加每个订单详细信息。

此 code/method 尚未经过测试,但应该可以让您了解该怎么做。

  1. 创建 2 个 object 类型的 SSIS 变量,一个用于 header,一个用于细节。
  2. 创建 2 个 Execute SQL 任务和 1 个 Script Task,如下所述:
  3. 设置您的任务以处理完整的结果集,类似于这些图片(显示了详细信息版本,对 Header 执行类似操作,但将结果映射到 Header object 和将您的查询更改为指向 header table):
  4. 编辑您的脚本任务并允许 DetailHeader 作为只读变量:
  5. 现在按照这些行编辑您的实际脚本(假设您有 1 个 header 行的 1 个详细信息行):

using System.IO;
using System.Linq;
using System.Data.OleDb;

// following to be inserted into Main() function
DataTable detailData = new DataTable();
DataTable headerData = new DataTable();
OleDbDataAdapter adapter = new OleDbDataAdapter();
adapter.Fill(detailData, Dts.Variables["User::Detail"].Value);
adapter.Fill(headerData, Dts.Variables["User::Header"].Value);

using (StreamWriter outfile = new StreamWriter("myoutput.csv"))
{
    // we are making the assumption that 
    for (var i = 0; i < detailData.Rows.Count; i++)
    {
        var detailFields = detailData.Rows[i].ItemArray.Select(field => field.ToString()).ToArray();
        var headerFields = headerData.Rows[i].ItemArray.Select(field => field.ToString()).ToArray();
        outfile.WriteLine(string.Join(",", detailFields));
        outfile.WriteLine(string.Join(",", headerFields));
    }
}

不是完整的答案,只是让您了解替代方法

SELECT Type, OrderBy, Col
FROM
(
   SELECT 'D' As Type, Ord as OrderBy, 
   Col1 + ',' + CAST(Col2 AS VARCHAR(50)) + ',' + Col3 As Col
   FROM Details
   UNION ALL
   SELECT 'H' As Type, Ord as OrderBy,
   Col1 + ',' + CAST(Col2 AS VARCHAR(50)) + ',' + Col3 As Col + ',' + Col4
   FROM Header
) S
ORDER BY OrderBy, Type

虽然丑陋,但只要将所有数据类型转换为 varchar 就可以工作

您可以将其包装在视图或存储过程中并从数据库中对其进行测试(在进入 SSIS 部分之前)。您甚至可以使用 BCP.EXE 而不是 SSIS

导出它

你这里有一列恰好包含这种数据:

 A,B,C
 D,E,F,G

从元数据的角度来看,始终只有一列

从 CSV 的角度来看,有可变列