阅读大活追加CSV和更新SQL Server C#

cu6pst1q  于 2023-11-14  发布在  SQL Server
关注(0)|答案(1)|浏览(178)

我试图读取常数追加csv文件[可能是在频率,如果15-30秒];(从1行开始,直到大约结束。超过500000行,随机添加行数),并插入数据到SQL Server,避免重复,缓慢和流入性能。
我使用.NET和C#作为主要语言。有没有C# / .NET方法可以帮助BULK只从CSV中删除特定的列?
当我尝试下面的代码时,它需要自己的时间来更新记录,这会影响性能,并且应用程序处于不响应模式。

  1. private void btnPlxl_Click(object sender, EventArgs e)
  2. {
  3. this.openFileDialog1 = new OpenFileDialog();
  4. this.openFileDialog1.ShowDialog();
  5. string fn;
  6. fn = this.openFileDialog1.FileName;
  7. MessageBox.Show("Selected file :" + fn);
  8. string connectionString;
  9. SqlConnection conn;
  10. connectionString = @"Data Source=VKB_LAP_KIRAN\SQLEXPRESS; Initial Catalog=ExpoProCli; User ID=sa;Password=Kiran@123";
  11. conn = new SqlConnection(connectionString);
  12. conn.Open();
  13. MessageBox.Show("Connection opened");
  14. // SELECT* FROM tbl_PS03File
  15. // BULK INSERT tbl_PS03file from "D:\F_PS03_06760_19102023.CSV" WITH(FORMAT = 'CSV');
  16. //DATAFILETYPE = 'char'.
  17. string sqlString = "BULK INSERT tbl_BOFile FROM 'D:\\pl.csv' WITH(FORMAT = 'CSV')";
  18. SqlCommand command = new SqlCommand(sqlString, conn);
  19. command.ExecuteNonQuery();
  20. MessageBox.Show("Bulk Inserted BackOffice File");
  21. conn.Close();
  22. MessageBox.Show("Connection Closed");
  23. }

字符串

vfhzx4xs

vfhzx4xs1#

你在这里提出了三个概念:

  • BULK ®特定型号
  • BULK色谱柱特定色谱柱
  • UI线程锁定(* 应用程序进入无响应模式 *)

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

为了避免重复阅读文件,我们需要保留行号引用。如果文件写入过程是流式字符,而不是整行写入追加,那么我们应该首先获得行数,以确定我们应该尝试读取的最后一行,否则我们可以根据命令影响的记录数追加行计数器。

BULK INSERT (Transact-SQL)

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

一个简单的实现,假设行是作为整行追加的,看起来像这样,注意我们在button click方法之外保留了对LastRow的引用:

  1. private long LastRow { get;set; } = 1; //Start at line 1, use 2 if you want to skip header rows
  2. ...
  3. private void btnPlxl_Click(object sender, EventArgs e)
  4. {
  5. ...
  6. string sqlString = $@"
  7. BULK INSERT tbl_BOFile
  8. FROM 'D:\pl.csv'
  9. WITH(FORMAT = 'CSV', FIRSTROW = {LastRow})
  10. ";
  11. SqlCommand command = new SqlCommand(sqlString, conn);
  12. var rows = command.ExecuteNonQuery();
  13. LastRow += rows;
  14. MessageBox.Show("Bulk Inserted BackOffice File");
  15. conn.Close();
  16. MessageBox.Show("Connection Closed");
  17. }

字符串
特定列的问题应该会改善SQL Server的执行时间,但是需要从文件中读取相同数量的字节到SQL Server中,因此根据您排除的列数以及时间丢失的位置,结果可能会有所不同。
这篇文章探讨了BULK INSERT into specific columns的一个简单解决方案:
最简单的方法是创建一个从目标表中复制的视图,列出你希望数据转到的列,按照它们在源文件中出现的顺序。然后BULK复制到你的视图中,而不是直接复制到表中。
然而,这依赖于SQL加载的文件中的列与目标表匹配,这意味着您仍然需要操作文件,或者您批量插入到临时表或staging表中,然后将这些行投影到 live 表中。
一种替代直接从活动文件中插入的方法,(IMO是一个更健壮的解决方案)是编写一个函数,将行提取到一个临时文件中,然后在将其移交给SQL之前,您还可以操作列。SQL Server可以独占访问该文件,而且文件大小也会小得多,而且一致。这将有助于减少争用,因为从文件本身阅读行不会锁定文件太长时间,我们可以处理重试如果数据库执行中存在其他暂时性问题。
看看这个相关的帖子,关于从共享访问的文件中阅读:Read Changes on a text file dynamically c#

展开查看全部

相关问题