本人在做一個數據庫 入庫工具。可以把文本文件(.txt文件)中的數據,篩選(要區分分隔符和數據)。導入到指定的數據庫表中。
思路是這樣的:
1.在內存中創建一個表ResourceTable,並創建數據行,同時規定了這個表的每個列的數據類型(這個很重要)。
2.然後,逐行讀取.txt文件。篩選。把數據和分隔符區分開來。並把要存入對應列的數據,轉換成該列的數據類型(也就是說轉換成ResourceTable中列的數據類型)。
3.把這個表導入到數據庫。
但是小弟在第2步。碰到了問題。
問題是:
怎麼根據ResourceTable列的數據類型,把要存入該列的數據進行類型轉換。這個要怎麼做?
描述一下問題吧。貼些代碼。免得像我在QQ群裡面一下,問了半天,沒人懂。我問了什麼?
這個是小弟的程序界面,大家可以大致的了解是個什麼東西。
這個是讀.txt文件的代碼段,
///
/// 讀取文本文件,獲取指定行數
///
/// 用於保存數據的table
/// 文本文件的路徑
/// 分隔字符串
/// 要讀取的行數
/// 如果獲取到指定的行數,則正常,否則返回false代表失敗。
public static bool ReaderText(DataTable saveTable,string TextFilePath,string SplitString,UInt64 RowsCount )
{
/*分隔措施*/
string[] data_mark = new string[] { "data" };
String[] sep_string = SplitString.Split(data_mark, StringSplitOptions.RemoveEmptyEntries); //通過切割字符串,把所有的非data標志的數據,判定為分隔符
string[] one_line; //文本文件中的一行
string badrow=null; //壞行,存在問題的行
/*構建文件流讀取器*/
StreamReader sr;
FileStream fs ;
try
{
fs= File.OpenRead(TextFilePath); //創建文件流對象
sr = new StreamReader(fs, Encoding.Default); //創建一個指向文件的流讀取器
}
catch (Exception)
{
return false; //出現異常,讀取失敗
throw;
}
/*讀取指定的行數並存入表中*/
for (UInt64 i = 0; i < RowsCount; i++)
{
try
{
DataRow one_row = saveTable.NewRow();
badrow=sr.ReadLine();
one_line = badrow.Split(sep_string, StringSplitOptions.RemoveEmptyEntries); //把取出來的分隔符數組作為切割標志,對從文本文件讀到的數據進行分隔
for (int j = 0; j < one_line.Length; j++) //創建行,並往行裡面添加數據
{
one_row[j] = one_line[j];
// MessageBox.Show(saveTable.Columns[j].DataType.FullName);
one_row[j]=(saveTable.Columns[j].DataType.FullName)one_line[j].ToString(); //【這裡需要把存入saveTable的數據進行類型轉換,
//轉換成和saveTable的對應列的數據類型一致。
//因為我的saveTable是把對應的列設置了數據類型的。
// (typeof(saveTable.Columns[j].DataType.FullName));
// System.Convert.(saveTable.Columns[j].DataType.FullName).
}
saveTable.Rows.Add(one_row); //把這一行添加到表裡面
Form1.getInstance().progressBar1.PerformStep();
}
catch (Exception)
{
BadRowsProcess(badrow, TextFilePath); //對壞行進行處理
// throw;
}
}
sr.Dispose();
fs.Dispose();
return true; //正常讀完了
}
這裡是構建那個ResourceTable的代碼段。
private void button_Insert_Click(object sender, EventArgs e) //開始入庫按鈕
{
ResourceTable = new DataTable();
ResourceTable.Clear();
/*構建一下源表*/
DataTable TargetTableDes = ADO.selectOracle("select column_name,data_type,DATA_LENGTH from user_tab_columns where table_name='" + comboBox1.SelectedItem.ToString() + "'");
foreach (DataRow item in TargetTableDes.Rows)
{
ResourceTable.Columns.Add("【" + item[0].ToString() + "】" + item[1].ToString() + "(" + item[2].ToString() + ")"); //增加列名
ResourceTable.Columns["【" + item[0].ToString() + "】" + item[1].ToString() + "(" + item[2].ToString() + ")"].DataType = Type.GetType(item[1].ToString()); //給列限制數據類型。
}
小弟想問,怎麼根據ResourceTable的列的數據類型,把存入這個列的數據,轉換成和這個列的數據類型一致的。
而且這個問題還有以下幾個特點:
1.ResourceTable的列不止一個,而且不同的列,數據類型可能不同。同時,用戶,可能把同樣的數據,導入不同的表,所以ResourceTable列的列數和列的數據類型。都是根據用戶的選擇,在程序運行期間確定的。
2.數據庫的類型和C#的類型,不完全相同。比如數據庫的date類型,等等。可能會碰到在數據庫的類型中有,而在C#的類型中沒有的情況。那這種情況要怎麼處理?
3.這個數據類型轉換語句,是要求性能的。因為可能要讀上百萬行的文本文件,而且對每一個列都要進行轉換。最好是一行代碼就可以完成這個功能。
好的啰嗦了點。求各位大神,指點指點,希望大家能看懂我的需求。也就是一個數據類型轉換的問題。
第一次提問啊。表達不清楚之處。多多諒解,要是還是看不懂,就問我。我再補充。
讀大文件最好是用流,一行一行的讀,讀完一行後馬上做分析,把分析的結果放在一個內存表中,當內存表的行數據達到一定數量時,就要把這些記錄同步到DB中,這樣保存內存占用合理不會內存溢出。