我是SSIS和C#编程的初学者,刚刚找到一份新工作,并且想打个分数。我之前创建了一个程序包,用于将制表符分隔的平面文件转换为SQL Server表,但是该平面文件是为转换而手动准备的。现在,我需要自动进行管道定界文件的转换,该文件的创建类似于报告,并且具有多个标题行和子标题行。从管道到制表符分隔的转换对我来说不是问题。但是,我只是找不到一种方法,也无法在线获得任何帮助来了解如何读取每条记录,确定其内容以及省略或写入记录。
我将下面显示的以下SSIS C#脚本仅从Main ()
进行编码,但是出现了以下错误,并且我不知道为什么得到它。你能帮我吗?
错误-(脚本任务1的错误:找不到脚本的二进制代码。请通过单击“编辑脚本”按钮在设计器中打开脚本,并确保脚本成功构建。脚本任务1的错误:任务验证。)
该脚本应该:
1)读取管道分隔平面文件中的每个记录
2)检查每行/记录以确定它们是否包含以下值,如果它们包含以下值,则不写记录:
•空格
•价值-“业务部门:”等
•值-“员工ID |员工名称|部门ID |部门| EE家庭电话|紧急联系人姓名|主要|电话|关系”
•最后一个值是标题。我想写这个标题的第一个匹配项,但此后不要再写其他任何匹配的项。
脚本:
public void Main()
{
string SourcePath = Dts.Variables["User::Source_Path"].Value.ToString();
string DestinationPath = Dts.Variables["User::Destination_Path"].Value.ToString();
string Line = string.Empty;
try
{
using (StreamReader sr = new StreamReader(SourcePath))
using (StreamWriter ds = new StreamWriter(DestinationPath))
{
while ((Line = sr.ReadLine()) != null)
{
// MessageBox.Show(Line);
if (Line == " ")
Console.WriteLine("Blank Line");
else
if (Line == "Business Unit: 069 - DEPT OF XXXX XXXXX")
Console.WriteLine("069 Heading");
else
if (Line == "Business Unit: 071 - DEPT. OF YYYYY YYYYYYY")
Console.WriteLine("071 Heading");
else
if (Line == "Empl Id | Employee Name | Dept Id | Department | EE Home Phone | Emergency Contact Name | Primary | Telephone | Relationship")
Console.WriteLine("Main Heading");
// write to destination file
ds.WriteLine(Dts.Variables["User::Destination_Path"].Value);
}
// close the stream
ds.Close();
//string data = sr.ReadToEnd();
//MessageBox.Show(data);
}
Dts.TaskResult = (int)ScriptResults.Success;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK);
}
答案 0 :(得分:0)
打印文件路径的原因是因为您使用保存文件路径的变量调用StreamWriter.WriteLine()
,而不是使用文本本身。初始化StreamWriter
时将使用文件路径,而调用WriteLine()
方法时将使用文本。我还建议按照以下步骤将您不想编写的文本存储在字符串变量中。如有必要,您可以添加其他将被过滤掉的字符串(即下面的“ TextToOmit”字符串)。您可能需要对要忽略的确切字符串进行几处修改,但是下面的代码将保留在第一个标头上,并删除后续的字符串。您可以删除Close()
方法,因为它是不必要的,因为该方法将在退出using
块时关闭。 String.IndexOf
方法也过滤掉带有空格的行,当找不到文本时,该方法返回-1。您提到了有关获得直接匹配的问题,可以将IndexOf
方法与StringComparision.CurrentCultureIgnoreCase
参数一起使用来匹配第一个匹配项,而不区分大小写。但是,使用这种方法时,您将要确保要忽略的文本不会出现在任何需要保留的记录中,下面的示例在初始代码段中。我假设您想将每条记录写在新行上,这就是为什么在构建输出文本时添加Environment.NewLine
属性的原因。
string sourcePath = Dts.Variables["User::Source_Path"].Value.ToString();
string destinationPath = Dts.Variables["User::Destination_Path"].Value.ToString();
string line = string.Empty;
string outputText = string.Empty;
string headerText = "YourHeaderLine";
string secondTextToOmit = "TextThatNeedsToBeOmitted";
string thirdTextToOmit = "TextThatNeedsToBeOmitted";
int headerCount = 0;
try
{
using (StreamReader sr = new StreamReader(sourcePath))
{
while ((line = sr.ReadLine()) != null)
{
//only write first occurance
if (line == headerText && headerCount == 0)
{
outputText = outputText + line + Environment.NewLine;
headerCount++;
}
else
//store text in variables to do checks all in same if statement
//IndexOf looks for while space
if (line.IndexOf(' ') < 0 && line != headerText
&& line != secondTextToOmit && line != thirdTextToOmit)
{
outputText = outputText + line + Environment.NewLine;
}
//initialize StreamWriter using file path
using (StreamWriter writer = new StreamWriter(destinationPath))
{
//write the string using filtered text
writer.WriteLine(outputText);
}
}
}
}
不区分大小写的匹配示例:
line.IndexOf(thirdTextToOmit, 0, StringComparison.CurrentCultureIgnoreCase) < 0