我试图读取常数追加csv文件[可能是在频率,如果15-30秒];(从1行开始,直到大约结束。超过500000行,随机添加行数),并插入数据到SQL Server,避免重复,缓慢和流入性能。
我使用.NET和C#作为主要语言。有没有C# / .NET方法可以帮助BULK只从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");
}
字符串
1条答案
按热度按时间vfhzx4xs1#
你在这里提出了三个概念:
第三个概念超出了范围,它本身是一个定义良好的主题。最佳实践将取决于您的运行时:
为了避免重复阅读文件,我们需要保留行号引用。如果文件写入过程是流式字符,而不是整行写入追加,那么我们应该首先获得行数,以确定我们应该尝试读取的最后一行,否则我们可以根据命令影响的记录数追加行计数器。
BULK INSERT (Transact-SQL)
一个简单的实现,假设行是作为整行追加的,看起来像这样,注意我们在button click方法之外保留了对
LastRow
的引用:LASTROW
,阅读文件中的行可以很快,但通常最好避免双重阅读文件,如果可以的话,请参阅What's the fastest way to count the total lines of text file in c#?的指针。字符串
特定列的问题应该会改善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#