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

时间:2017-02-25 02:02:05

标签: sql-server ssis etl ssis-2012

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

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

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

Current Package如下所示:

  1. 获取所有订单的清单。将orderid作为变量传递。
  2. For循环容器遍历每个orderid,运行数据任务流以获取订单的订单详细信息。运行数据任务以获取订单标题。 我只是遇到一个问题,将每一行输出到Flat文件。
  3. 如果有人能提供帮助,我们将非常感激。我已经苦苦挣扎了一个星期了。如果任何人都可以启动我的脚本组件代码看起来应该是非常值得赞赏的。

    我已添加到目前为止的内容: 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;
    
        }
    

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

2 个答案:

答案 0 :(得分:1)

此代码/方法尚未经过测试,但应该让您知道该怎么做。

  1. 创建2个类型为对象的SSIS变量,一个用于标题,一个用于详细信息。 Variables
  2. 创建2个Execute SQL个任务和1个Script Task,如下所示:Overview
  3. 设置您的任务以处理完整的结果集,类似于这些图片(显示详细信息版本,类似于标题,但将结果映射到标题对象并将您的查询更改为指向标题表):{{3 }} ExecSql
  4. 修改您的脚本任务,并允许DetailHeader作为只读变量:ExecSql2
  5. 现在沿着这些行编辑您的实际脚本(假设您有1个标题行的1个详细信息行):
  6.   

    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));
        }
    }
    

答案 1 :(得分:1)

不是一个完整的答案,只是让你走上另类方法的轨道

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角度来看,有可变列