阅读大型实时追加 CSV 并更新 sql server C#

问题描述 投票:0回答:1

我正在尝试读取不断附加的 csv 文件*[可能频率为 15-30 秒]*; (从 1 行开始,直到大约超过 500000 行,随机添加行数); 并在sql server中插入数据,避免重复、缓慢和流入性能 使用 .NET 以 C# 作为主要语言。任何有助于仅使用特定的 BULK INSERT 的 C#.NET 方法 来自 CSV 的列?

当我尝试以下代码时,它需要花费自己的时间来更新记录,这会损害 性能和应用程序进入无响应模式。



private void btnPlxl_Click(object sender, EventArgs e)
    {

        this.openFileDialog1 = new OpenFileDialog();

        this.openFileDialog1.ShowDialog();
        string fn;
        fn = this.openFileDialog1.FileName;
        MessageBox.Show("Selected file :" + fn);

        string connectionString;
        SqlConnection conn;
        connectionString = @"Data Source=VKB_LAP_KIRAN\SQLEXPRESS; Initial Catalog=ExpoProCli; User ID=sa;Password=Kiran@123";
        conn = new SqlConnection(connectionString);
        conn.Open();
        MessageBox.Show("Connection opened");



        //  SELECT* FROM tbl_PS03File
        // BULK INSERT tbl_PS03file from "D:\F_PS03_06760_19102023.CSV" WITH(FORMAT = 'CSV');
        //DATAFILETYPE = 'char'.

        string sqlString = "BULK INSERT tbl_BOFile FROM 'D:\\pl.csv' WITH(FORMAT = 'CSV')";


        SqlCommand command = new SqlCommand(sqlString, conn);


        command.ExecuteNonQuery();
        MessageBox.Show("Bulk Inserted BackOffice File");

        conn.Close();
        MessageBox.Show("Connection Closed");




    }
c# multithreading csv asynchronous bulkinsert
1个回答
0
投票

您在这里提出了 3 个概念:

  • 批量插入特定行
  • 批量插入特定列
  • UI 线程锁定(应用程序进入无响应模式

第三个概念超出了范围,它本身就是一个定义明确的主题。最佳实践将取决于您的运行时间:

为了避免从实时文件中重复读取,我们需要保留行号引用。如果文件写入过程是流字符而不是整行写入追加,那么我们应该首先获取行数来识别我们应该尝试读取的最后一行,否则我们可以根据受命令影响的记录数追加行号.

批量插入 (Transact-SQL)

  • 第一行=第一行 指定要加载的第一行的行号。默认为指定数据文件中的第一行。 FIRSTROW 是从 1 开始的。
  • 最后一行=最后一行 指定要加载的最后一行的行号。默认为 0,表示指定数据文件的最后一行。

假设行作为整行附加的简单实现如下所示,请注意,我们在按钮单击方法外部保留对

LastRow
的引用:

private long LastRow { get;set; } = 1; //Start at line 1, use 2 if you want to skip header rows
...

private void btnPlxl_Click(object sender, EventArgs e)
{
    ...

    string sqlString = $@"
        BULK INSERT tbl_BOFile 
        FROM 'D:\pl.csv' 
        WITH(FORMAT = 'CSV', FIRSTROW = {LastRow})
    ";
    SqlCommand command = new SqlCommand(sqlString, conn);
    var rows = command.ExecuteNonQuery();
    LastRow += rows;
    
    MessageBox.Show("Bulk Inserted BackOffice File");
    conn.Close();
    MessageBox.Show("Connection Closed");
}

特定列问题应该会改善 SQL INSERT 执行时间,但需要从文件中将相同数量的字节读入 SQL Server,因此根据您排除的列数以及时间损失的位置,您的结果可能会有所不同。各有不同。

这篇文章探讨了一个简单的解决方案批量插入特定列

最简单的方法是创建一个从目标表中选择的视图,列出您想要数据进入的列,按照它们在源文件中出现的顺序。然后批量插入到您的视图中,而不是直接插入到表中。

但是,这依赖于 SQL 加载的文件中与目标表匹配的列,这意味着您仍然需要操作该文件,或者批量插入到临时表或临时表中,然后将这些行投影到 live 表中。

在写入时直接从实时文件插入的另一种方法是编写一个将行提取到临时文件的函数,然后您还可以在将其移交给 SQL 之前操作列。然后,SQL Server 可以独占访问该文件,但文件大小也会显着减小且一致。它将有助于减少争用,因为从文件本身读取行不应将文件锁定太长时间,并且如果数据库执行存在其他暂时性问题,我们可以处理重试。

查看有关从具有共享访问权限的文件中读取内容的相关文章:动态读取文本文件上的更改 c#

© www.soinside.com 2019 - 2024. All rights reserved.