[英]SSIS: How to read, omit by matching, and write records from pipe delimited flat file in C#
我是SSIS和C#編程的初學者,剛剛找到一份新工作,並且想打個分數。 我之前創建了一個程序包,用於將制表符分隔的平面文件轉換為SQL Server表,但是該平面文件是為轉換而手動准備的。 現在,我需要自動進行管道定界文件的轉換,該文件的創建類似於報告,並且具有多個標題行和子標題行。 從管道到制表符分隔的轉換對我來說不是問題。 但是,我只是找不到一種方法,也無法在線獲得任何幫助來了解如何讀取每條記錄,確定其內容以及省略或寫入記錄。
我將下面顯示的以下SSIS C#腳本僅從Main ()
組合在一起,但出現以下錯誤,而且我不知道為什么得到它。 你能幫我嗎?
錯誤-(腳本任務1發生錯誤:找不到腳本的二進制代碼。請通過單擊“編輯腳本”按鈕在設計器中打開腳本,並確保腳本成功構建。腳本任務1發生錯誤:任務驗證期間出錯。 )
該腳本應該:
1)讀取管道分隔平面文件中的每個記錄
2)檢查每行/記錄以確定它們是否包含以下值,如果它們包含以下值,則不寫記錄:
•空間
•價值-“業務單位:”等
•值-“ Empl ID |雇員名稱| Dept 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);
}
之所以要打印文件路徑,是因為您要使用保存文件路徑的變量來調用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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.