我试图从SSIS(2008 R2)中的固定宽度平面文件加载数据,但第一行包含以下数据:
最好的方法是什么?我对SSIS比较陌生,所以我尝试使用行计数和条件拆分来分离第一行,但我不确定如何解析Flat文件之外的数据进口商。我已经读到使用脚本转换可以工作,但我不知道代码应该是什么......
举例来说,如果我的平面数据看起来像:
Hamilton Beach 20150410 Sunny
鲍勃男蓝黑色
Bill Male BrownBrown
GeorgeMale GreenBlonde
JackieFemaleGreenBlack
Jill FemaleBlue Black
它应该在输出表中:
Hamilton Beach,20150410,Sunny,Bob,Male,Blue,Black
Hamilton Beach,20150410,Sunny,Bill,Male,Brown,Brown
Hamilton Beach,20150410,Sunny,George,Male,Green,Blonde
Hamilton Beach,20150410,Sunny,Jackie,Female,Green,Black
Hamilton Beach,20150410,Sunny,Jill,Female,Blue,Black
答案 0 :(得分:0)
你很幸运。 SSIS不支持混合记录类型,但您可以使用它,因为您只有1个标题行。
我的实现看起来像一个脚本任务,它读取我文件的第一行和一个读取其余数据的数据流任务。
这个很简单。创建一个SSIS变量,将其命名为String类型FirstLine
。将该值作为读/写值传递到脚本任务中。
使用此答案中的代码
Read only the first few lines of text from a file
现在您只需要将line1
的值推入我们的SSIS级别变量。看起来像是
Dts.Variables["User::FirstLine"].Value = line1;
这假设您希望将整行存储到FirstLine中。如果您需要将其分配到单个字段中,那么您将需要实现该逻辑。您没有提供有关如何将“Hamilton Beach 20150410 Sunny”划分为单个部分的指导,但上述逻辑仍然适用。解析并分配到不同的SSIS级别变量。
我的具体实现创建了3个SSIS变量,所有类型字符串
以下代码表示已经链接的内容
using System;
using System.Data;
using System.IO;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
namespace ST_7edd5e6df63a4837afac15b86c21d639.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
public void Main()
{
// User::HeaderIHaveNoIdeaWhatThisIs,User::HeaderObservationDate,User::HeaderWeather
// https://stackoverflow.com/questions/9439733/read-only-the-first-few-lines-of-text-from-a-file
string line1 = string.Empty;
using (StreamReader reader = new StreamReader(@"C:\ssisdata\so_29811494.txt"))
{
line1 = reader.ReadLine();
}
// Magic here to understand how to split this out. Assuming this is also fixed width
// Horrible, hard coded brittle approach taken
//Hamilton Beach 20150410 Sunny
string h1, h2, h3;
h1 = line1.Substring(0, 20).TrimEnd();
h2 = line1.Substring(20, 12).TrimEnd();
h3 = line1.Substring(32, line1.Length - 32);
Dts.Variables["User::HeaderIHaveNoIdeaWhatThisIs"].Value = h1;
Dts.Variables["User::HeaderObservationDate"].Value = h2;
Dts.Variables["User::HeaderWeather"].Value = h3;
Dts.TaskResult = (int)ScriptResults.Success;
}
}
}
在平面文件连接管理器中,您希望将Skip标题行的值从0更改为1.这表示在我们读取前N行之前,不应开始验证数据和解析。像往常一样定义连接管理器。
将数据流任务连接到上面的脚本任务。在数据流任务中,使用平面文件源并连接派生列组件。派生列组件是我们如何将SSIS变量中的值传递到数据流中的。添加名为HeaderColumn
的新列,并使用类似@[User::FirstLine]
的表达式。
如果您注意到右侧的列表示数据类型为DT_NTEXT
,则可能与目标列定义不匹配。您可能需要执行类似变量SUBSTRING(@[User::FirstLine], 1, 20)
的子字符串。这导致数据类型为DT_WSTR,长度为20.您的目标是使此匹配成为目标定义。
您可能还需要使用DT_STR数据类型而不是DT_WSTR。在这种情况下,请在子字符串操作(DT_STR, 20, 1252)SUBSTRING(@[User::FirstLine], 1, 20)
我根据提供的数据定义了我的文件(点击编辑问题以获取定义而不剥离空格)
Hamilton Beach 20150410 Sunny
Bob Male Blue Black
Bill Male BrownBrown
GeorgeMale GreenBlonde
JackieFemaleGreenBlack
Jill FemaleBlue Black