我想从文本文件中读取并将其第一列插入数据库中的行。
这是文本文件的样子:
1264311 | SMS_DR | DELIVERED
373414 | SMS_DR | EXPIRED
418 | SMS_DR | UNDELIVERABLE
1628984 | SMS_MT |
我想只获取带有整数值的第一列,并将它们作为一行插入我的数据库中以获得此值:
DELIVERED EXPIRED UNDELIVERABLE BLABLA
1264311 373414 418 1628984
当我运行我的代码时,它会插入所有4行,这是我的代码:
sr1 = new StreamReader("C:\\Users\\adamoui\\Desktop\\Statjbm_20161009.txt");
string[] allLines1 = File.ReadAllLines("C:\\Users\\adamoui\\Desktop\\Statjbm_20161009.txt");
for (int i = 0; i < allLines1.Length; i++)
{
string[] column = allLines1[i].Split(new char[] { '|' });
SqlCommand cmdJBM = new SqlCommand("INSERT INTO dbo.StatJBM_NEW (Noeud, Total_MT, Date, DELIVERED, EXPIRED, UNDELIVERABLE) VALUES (@Noeud, @Total_MT, @Date, @DELIVERED, @EXPIRED, @UNDELIVERABLE)", con);
cmdJBM.Parameters.AddWithValue("@Noeud", "JBM");
cmdJBM.Parameters.AddWithValue("@DELIVERED", column[0]);
cmdJBM.Parameters.AddWithValue("@EXPIRED", column[0]);
cmdJBM.Parameters.AddWithValue("@UNDELIVERABLE", column[0]);
cmdJBM.Parameters.AddWithValue("@Total_MT", column[0]);
cmdJBM.Parameters.AddWithValue("@Date", DateTime.Now.AddDays(-1));
cmdJBM.ExecuteNonQuery();
}
con.Close();
结果:
答案 0 :(得分:2)
您的代码为每一行插入一个插入,使用第一列作为所有参数。可能不是你的想法。试试这个:
var values = allLines1.Split('|')
.Select(arr => arr[0])
.ToArray();
SqlCommand cmdJBM = new SqlCommand(@"INSERT INTO dbo.StatJBM_NEW
(Noeud, Total_MT, Date, DELIVERED, EXPIRED,
UNDELIVERABLE) VALUES (@Noeud, @Total_MT, @Date,
@DELIVERED, @EXPIRED, @UNDELIVERABLE)", con);
cmdJBM.Parameters.AddWithValue("@Noeud", "JBM");
cmdJBM.Parameters.AddWithValue("@DELIVERED", values[0]);
cmdJBM.Parameters.AddWithValue("@EXPIRED", values[1]);
cmdJBM.Parameters.AddWithValue("@UNDELIVERABLE", values[2]);
cmdJBM.Parameters.AddWithValue("@Total_MT", values[3]);
cmdJBM.Parameters.AddWithValue("@Date", DateTime.Now.AddDays(-1));
cmdJBM.ExecuteNonQuery();
答案 1 :(得分:1)
摆脱循环并做这样的事情:
cmdJBM.Parameters.AddWithValue("@DELIVERED", allLines1[0].Split(new char[] { '|' })[0]);
如果您知道文件将具有的索引和确切行数,则可以将索引直接放入代码中。
答案 2 :(得分:1)
你需要这样的东西:
var delivered = allLines[0].Split(new char[] { '|' })[0];
var expired = allLines[1].Split(new char[] { '|' })[0];
var undeliverable = allLines[2].Split(new char[] { '|' })[0];
....
cmdJBM.Parameters.AddWithValue("@DELIVERED", delivered);
cmdJBM.Parameters.AddWithValue("@EXPIRED", expired);
cmdJBM.Parameters.AddWithValue("@UNDELIVERABLE", undeliverable);
答案 3 :(得分:1)
U有逻辑错误......在列数组中是当前行的拆分。
但为什么要创建sr1 = new StreamReader并且不使用它?
File.ReadAllLines是小文件的快速版本...但对于大文件,您可以获得OutOfMemoryException。
试试这个。
课程计划 { static void Main(string [] args) {
//current line from the file
string line;
//filereader
using (var file = new StreamReader("C:\\Users\\adamoui\\Desktop\\Statjbm_20161009.txt"))
{
//list for the first columns
var firstColumnInFile = new List<string>();
//read every line
while ((line = file.ReadLine()) != null)
{
//split line
var items = line.Split('|');
// add the first column in the list;
firstColumnInFile.Add(items.First());
}
if(firstColumnInFile.Count < 4)
return;
SqlCommand cmdJBM = new SqlCommand(@"INSERT INTO dbo.StatJBM_NEW
(Noeud, Total_MT, Date, DELIVERED, EXPIRED,
UNDELIVERABLE) VALUES (@Noeud, @Total_MT, @Date,
@DELIVERED, @EXPIRED, @UNDELIVERABLE)", con);
cmdJBM.Parameters.AddWithValue("@Noeud", "JBM");
cmdJBM.Parameters.AddWithValue("@DELIVERED", firstColumnInFile[0]); //first column
cmdJBM.Parameters.AddWithValue("@EXPIRED", firstColumnInFile[1]); //second column
cmdJBM.Parameters.AddWithValue("@UNDELIVERABLE", firstColumnInFile[2]); //third column
cmdJBM.Parameters.AddWithValue("@Total_MT", firstColumnInFile[3]); //...
cmdJBM.Parameters.AddWithValue("@Date", DateTime.Now.AddDays(-1));
}
}
}
答案 4 :(得分:0)
首先使用StreamReader
打开文件,然后使用File.ReadAllLines()
阅读内容是无用的(并且您保留文件,因为您没有处置StreamReader
。)
假设文件格式正确(并且使用所有进程内存并不大),请先阅读其内容:
var allLines = File.ReadAllLines(@"C:\Users\adamoui\Desktop\Statjbm_20161009.txt");
然后删除不需要的字段(只需两个令牌,我们不需要创建我们不使用的2X字符串):
var allValues = allLines.Select(x => x.Split(new char[] { '|' }, 2)[0]);
现在你需要将4行4分组。我首先介绍一个你可以在别处重复使用的辅助函数(这里没有错误检查):
static IEnumerable<int> Range(int start, int count, int step) {
for (int i=0; i < count; i += step)
yield return start + i;
}
现在我们可以根据需要遍历我们的值:
var records = Range(0, allValues.Length, 4).Select(x => {
return new {
Delivered = allValues[x + 0],
Expired = allValues[x + 1],
// ...
};
});
我们还介绍一些常量来清理你的代码:
const string InsertRecordCommand = "INSERT INTO dbo.StatJBM_NEW (Noeud, Total_MT, Date, DELIVERED, EXPIRED, UNDELIVERABLE) VALUES (@Noeud, @Total_MT, @Date, @DELIVERED, @EXPIRED, @UNDELIVERABLE)";
将所有东西放在一起(在必要时也处理一次性物品):
var allValues = File.ReadAllLines(@"C:\Users\adamoui\Desktop\Statjbm_20161009.txt")
.Select(x => x.Split(new char[] { '|' }, 2)[0])
.ToArray();
var yesterday = DateTime.Now.AddDays(-1);
var records = Range(0, allValues.Length, 4).Select(x => {
return new {
Noeud = "JBM",
Delivered = allValues[x + 0],
Expired = allValues[x + 1],
Undeliverable = allValues[x + 2],
TotalMt = allValeus[x + 3],
Date = yesterday
};
});
foreach (var record in records)
{
using (var command = new SqlCommand(InsertRecordCommand , con))
{
command.Parameters.AddWithValue("@Noeud", record.Noeud);
command.Parameters.AddWithValue("@DELIVERED", record.Delivered);
command.Parameters.AddWithValue("@EXPIRED", record.Expired);
command.Parameters.AddWithValue("@UNDELIVERABLE", record.Undeliverable);
command.Parameters.AddWithValue("@Total_MT", record.TotalMt);
command.Parameters.AddWithValue("@Date", record.Date);
command.ExecuteNonQuery();
}
}
现在也许是时候简化代码了。您可能希望使用像Dapper这样的轻量级映射器:
var allValues = File.ReadAllLines(@"C:\Users\adamoui\Desktop\Statjbm_20161009.txt")
.Select(x => x.Split(new char[] { '|' }, 2)[0])
.ToArray();
var yesterday = DateTime.Now.AddDays(-1);
con.Insert(Range(0, allValues.Length, 4).Select(x => {
return new {
Noeud = "JBM",
Delivered = allValues[x + 0],
Expired = allValues[x + 1],
Undeliverable = allValues[x + 2],
Total_Mt = allValeus[x + 3],
Date = yesterday
};
}));
全部(我没有提及不硬编码路径和使用Environment.GetFolder()
,因为我想这只是一个例子。)有关其配置和约定的更多详细信息,请参阅Dapper文档,请注意,如果没有贡献,它也可能是这样的:
foreach (var record in records)
con.Execute(InsertRecordCommand, record);