简体   繁体   English

将txt文件插入数据库

[英]Inserting a txt file into database

public partial class Form1 : Form
{

    public SqlConnection con = new SqlConnection(@"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\Alexander\Desktop\Archivos.mdf;Integrated Security=True;Connect Timeout=30");



    private void Readbtn_Click(object sender, EventArgs e)
    {
         con.Open();
         Propiedades prop = new Propiedades();
         List<string> myValues = new List<string>();

         string line;

       StreamReader file = new StreamReader(@"c:\temp\archivo.txt");
        if ((line = file.ReadLine()) != null)
        {
            string[] fields = line.Split(',');
            prop.matricula = fields[0].ToString();
            prop.nombre = fields[1].ToString();
            prop.sueldo = decimal.Parse(fields[2]); 

            for (int i = 0; i < fields.Length; i++)
            {
                listBox1.Items.Add(fields[i]);
            }

        }



     SqlCommand cmd = new SqlCommand("INSERT INTO Archivos(Codigo, Nombre, Sueldo) VALUES (@Matricula, @Nombre, @Sueldo", con);
     cmd.Parameters.AddWithValue("@Matricula", prop.matricula);
     cmd.Parameters.AddWithValue("@Nombre", prop.nombre);
     cmd.Parameters.AddWithValue("@Sueldo", prop.sueldo);
     cmd.ExecuteNonQuery();

     con.Close();


 }

Hello Guys, I just need a little bit of help on modifying this code. 大家好,我只需要一点帮助来修改此代码。 I already have this to save the first line of the text file but I dont have any ideas on how to make it read the other lines. 我已经有了保存文本文件第一行的方法,但是我对如何使其读取其他行一无所知。 Also I would like to validate that if the SQL table contains already that info, it will launch an exception or message box letting the user know that the file already exist. 我还要验证一下,如果SQL表已经包含该信息,它将启动异常或消息框,让用户知道该文件已经存在。 Please help 请帮忙

I would recomend reading the file line by line, adding the values to a DataTable and then using SQL Bulk Insert to store it to the database. 我建议您逐行读取文件,将值添加到DataTable中 ,然后使用SQL Bulk Insert将其存储到数据库中。

It would be something like 就像

int batchSize = 10000;

SqlBulkCopy bc = new SqlBulkCopy(con);

DataTable dtArchivos = new DataTable();
dtArchivos.Columns.AddRange(new []
{
    new DataColumn("Codigo", typeof(string)), 
    new DataColumn("Nombre", typeof(string)), 
    new DataColumn("Sueldo", typeof(decimal)), 
});
StreamReader file = new StreamReader(@"c:\temp\archivo.txt");
string line = file.ReadLine();
while (line != null)
{
    string[] fields = line.Split(',');
    DataRow dr = dtArchivos.NewRow();
    dr["Codigo"] = fields[0].ToString();
    dr["Nombre"] = fields[1].ToString();
    dr["Sueldo"] = decimal.Parse(fields[2]);
    dtArchivos.Rows.Add(dr);

    if (dtArchivos.Rows.Count == batchSize)
    {
        bc.WriteToServer(dtArchivos);
        dtArchivos.Clear();
    }
    line = file.ReadLine();
}
bc.WriteToServer(dtArchivos);

I added some logic to do batching, as a large file might cause the application to run out of memory due to the size of the DataTable. 我添加了一些逻辑来进行批处理,因为大文件可能由于DataTable的大小而导致应用程序用尽内存。

There are a few things you need to do the the first that jumps out at me is that you want to use a while loop in place of your first if statement 您需要做一些事情,第一个让我跳出来的事情是您想使用while循环代替第一个if语句

    while ((line = file.ReadLine()) != null)
    {
        string[] fields = line.Split(',');
        prop.matricula = fields[0].ToString();
        prop.nombre = fields[1].ToString();
        prop.sueldo = decimal.Parse(fields[2]); 

        for (int i = 0; i < fields.Length; i++)
        {
            listBox1.Items.Add(fields[i]);
        }

    }

Also depending how you want to display the items in the list box you may want to use instead of that internal for loop: 另外,还取决于您要如何在列表框中显示项目,而不是内部的for循环:

listBox1.Items.Add(prop.matricula+','+prop.nombre+',prop.sueldo.toString());

First of all, consider using LINQ for your code - if you are not overly concerned about slightly more overhead, LINQ will make your life a whole lot easier. 首先,考虑将LINQ用于您的代码-如果您不太担心额外的开销,LINQ将使您的生活变得更加轻松。 It will automatically cache the information for you, and can be more efficient for a lot of things, not to mention that the code is a lot easier to understand at times. 它会自动为您缓存信息,并且在很多事情上会更高效,更不用说代码有时更容易理解了。 For this, you would need to, in Visual Studio, create a ado.net model of the database, which shouldn't take too long. 为此,您需要在Visual Studio中创建数据库的ado.net模型,该模型不会花费太长时间。 The precise way, I think, would be to 我认为,确切的方法是

File -> Add Item -> Add new Item

or something of the like, then searching for ado.net entity. 或类似的东西,然后搜索ado.net实体。 Then, just fill in the details that it asks. 然后,只需填写它要求的详细信息。 You can then use this entity (if you can't find out how to do it, then please reply so that I can fix it as need be) to add data, using the way that you specified. 然后,您可以使用您指定的方式使用该实体(如果无法找到方法,请回复,以便我可以根据需要进行修复)。

Now, the reason why it may not be working code be a code problem. 现在,它可能无法正常工作的原因是一个代码问题。 I think using the seperator may be the problem, and the following ammended code may be helpful: 我认为使用分隔符可能是问题所在,以下修改后的代码可能会有所帮助:

StreamReader file = new StreamReader(@"c:\temp\archivo.txt");

    while(file.Read()){

    //YOUR CODE FOR CONCATENATING DATA HERE
}

The reason is that the reader would read until it has a return value of False or Null. 原因是读取器将读取直到其返回值为False或Null。 Your code for some reason seems to be leaving after the first line, and this may solve it. 由于某种原因,您的代码似乎在第一行之后离开,这可能会解决它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM