C# - 将第一个列从文本文件插入数据库

时间:2016-10-11 12:42:01

标签: c# mysql sql

我想从文本文件中读取并将其第一列插入数据库中的行。

这是文本文件的样子:

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();

结果:

enter image description here

5 个答案:

答案 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);