65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 SqlBulkCopy 读取 .CSV 文件并将数据插入到 SQL 表

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.70/5 (7投票s)

2010年2月11日

CPOL

2分钟阅读

viewsIcon

93367

downloadIcon

2796

在本文中,我们将讨论如何使用 sqlbulkcopy。

引言

对于程序员/用户来说,常见的情况是需要将来自不同数据源的数据插入到 sqlserver 数据库表中。使用 sqlserver 集成的导入数据功能很容易做到。但是,如果您使用的是 sqlexpress,它是一个轻量级版本,不支持数据导入,该怎么办?

而且,数据导入功能有时可能无法满足业务需求。您可能不希望用户直接访问数据库。

如果您有一个包含 10000000 行的文件,并且在读取每一行后需要进行一些验证,并需要使用特定的编程逻辑进行解析,该怎么办?直接数据导入在那个时候将不起作用。

最好在代码中实现您的业务逻辑,而不是在数据库中使用存储过程、视图和函数。编写一个包含 3000 行的存储过程不是一个好主意。当调试这种存储过程时,您肯定会遇到麻烦。InsertDeleteUpdateSelect 语句最适合在没有验证的情况下在数据库中执行。

解决此问题

有很多方法可以解决这类问题。但最常见的方法是

  1. 您可以使用 SQL 命令
  2. 您可以使用 SQLBulkCopy (比 sqlcommand 更快,但不会触发数据库触发器)

在本文中,我们将讨论如何使用 sqlbulkcopy。

以下是分步解决方案

  1. 首先,我们将使用以下代码创建 sqltable。您需要在数据库查询窗口中执行此操作
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Company]') 
    and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [dbo].[Company]
    GO
    CREATE TABLE [dbo].[Company] (
    [CompanyName] [varchar] (500) 
    COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
    [Volume] [varchar] (500) 
    COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL 
    ) ON [PRIMARY]
    GO
  2. 其次,我们将创建一个项目。并将以下控件放置在默认的 Form1 窗体中,并同时放置代码。
    1. 1 个文本框用于指定服务器配置。
    2. 1 个文本框用于指定要读取的文件的文件路径。
    3. 1 个文本框用于指定数据存储的位置。
    4. 1 个打开文件对话框以打开指定的文件。
    5. 一个按钮,命名为 btnLoadFile 以加载文件路径
      private void btnLoadFile_Click(object sender, EventArgs e)
      {
          try
          {
              //I have used a open file Dialog to let the 
              //program know where the file is located
              DialogResult dResult = new DialogResult(); 
              //Dialog result sets the openfile dialog result
              dResult = openFileDialog1.ShowDialog();
              if (dResult == DialogResult.OK)
              //If dialog result is ok, then show the file 
              //name and path in the Text box
              { 
                  txtFilePath.Text = openFileDialog1.FileName;
              }
              else
              {
                  return; //If Dialog result is other than ok, then do nothing
              }
          }
          catch (Exception exp)
          {
              MessageBox.Show(exp.Message);//Catch any exception if occurs
          }
      }
    6. 一个 DataGridView 控件以显示数据
    7. 一个按钮,命名为 btnLoadData 以将数据从文件加载到 gridview
      private void btnLoadData_Click(object sender, EventArgs e)
      {
          try
          {
          if (string.IsNullOrEmpty(txtFilePath.Text.Trim())) //Check if 
      						//file was supplied
          {
              MessageBox.Show("Please supply file name");
              return;
          }
          System.IO.StreamReader rdr = 
          new System.IO.StreamReader(txtFilePath.Text.Trim());
          
          //Stream reader reads a file. File path 
          //and name are supplied from where to read the file. 
          string inputLine = "";
          DataTable dt = new DataTable(); 
          //A data table is similar to a Database table. 
          //Define the columns.
          dt.Columns.Add("CompanyName");
          dt.Columns.Add("Volume");
          DataRow row; //Declare a row, which will be added to the above data table
          while ((inputLine = rdr.ReadLine()) != null) 
          //Read while the line is not null
          {
              string[] arr;
              arr = inputLine.Split(','); 
              //splitting the line which was read by the stream reader object
              row = dt.NewRow();
              row["Companyname"] = arr[0];
              row["Volume"] = arr[1];
              dt.Rows.Add(row);
          }
          dt.Rows.RemoveAt(0); //Remove the first column since its 
          //the column name not necessary to insert in the database table
          dataGridView1.DataSource = dt; //setting the data source to the gridview
          rdr.Close(); //release the stream reader
          }
          catch (Exception)
          {
              throw;
          }
      }
    8. 一个按钮,命名为 btnSaveFile 以将原始数据保存到数据库。
      private void btnSaveFile_Click(object sender, EventArgs e)
      {
          try
          {
              if (string.IsNullOrEmpty(txtServerConfiguration.Text.Trim()))
               //Check if server exists
              {
                  MessageBox.Show("Please supply Server Configuration");
                  return;
              }
              if (string.IsNullOrEmpty(txtTableName.Text.Trim())) 
              //Check if Table name was provided 
              {
                  MessageBox.Show("Please supply Table Name");
                  return;
              }
              SqlBulkCopy sqlbulkCopy = new 
              SqlBulkCopy(txtServerConfiguration.Text.Trim()); 
              //Define the Server Configuration
              sqlbulkCopy.DestinationTableName = txtTableName.Text.Trim(); 
              //You need to define the target table name where 
              //the data will be copied
              //Since the requirement is not to read data directly from the file
              //I have included a gridview, where the 
              //raw data will be shown to the user.
              //So that the user can change the data if he wants
              for (int i = 0; i < dataGridView1.ColumnCount; i++) 
              //reading the column names 
              {
                  sqlbulkCopy.ColumnMappings.Add(
                  dataGridView1.Columns[i].Name, 
                  dataGridView1.Columns[i].Name);
                  //Column mapping , supplying source column 
                  //and destination column
              }
              DataTable dt = new DataTable();
              dt = (DataTable)dataGridView1.DataSource;
              //Storing the data in a data table, though you can do it by 
              //directly passing Grid View Data Source to the following function
              sqlbulkCopy.WriteToServer(dt);
              sqlbulkCopy.Close();//Release the resources
              MessageBox.Show("Saved Successfully");
          }
          catch (Exception exp)
          {
              MessageBox.Show(exp.Message);//Catch any exception if occurs
          }
      }

关注点

我无法在任何地方找到像这样的完整解决方案。我学习了如何使用 SQL bulk copy 将文件读取并写入数据库表。由于生活中会发生错误,任何评论/信息/激烈的反应都将受到欢迎。

历史

  • 2010 年 2 月 11 日:初始发布

我会不时更新这篇文章。

© . All rights reserved.