我目前正在创建一个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如下所示:
如果有人能提供帮助,我们将非常感激。我已经苦苦挣扎了一个星期了。如果任何人都可以启动我的脚本组件代码看起来应该是非常值得赞赏的。
我已添加到目前为止的内容: 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;
}
但是每次我运行它都会出错。我在这里错过了什么吗?另外,如何在一开始只创建一个文件一次。这意味着每次运行此包时,它将创建一个带有日期戳的文件,并且每次都附加到它。下次包运行时,它将创建一个带有新日期戳的新文件,并根据订单号附加每个订单详细信息。
答案 0 :(得分:1)
此代码/方法尚未经过测试,但应该让您知道该怎么做。
Execute SQL
个任务和1个Script Task
,如下所示: Detail
和Header
作为只读变量: 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角度来看,有可变列