首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 高效匯入 Excel 至 SQL Server:SqlBulkCopy 實戰指南

     編輯:關於C#

為什麼選擇 SqlBulkCopy?

傳統做法逐筆 INSERT 或拼接 SQL 字串,不僅效能低落,還易受 SQL 注入攻擊。.NET Framework 內建的 System.Data.SqlClient.SqlBulkCopy 類別,專為大量資料高效匯入 SQL Server 設計,速度極快且程式碼簡潔。

完整範例程式碼

using System;
using System.Data;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Data.SqlClient;

namespace WindowsApplication2
{
    public partial class Form1 : Form
    {
        public Form1() { InitializeComponent(); }

        private void button1_Click(object sender, EventArgs e)
        {
            string connString = "server=localhost;uid=sa;pwd=sqlgis;database=master";
            OpenFileDialog fd = new OpenFileDialog();
            if (fd.ShowDialog() == DialogResult.OK)
            {
                TransferData(fd.FileName, "sheet1", connString);
            }
        }

        public void TransferData(string excelFile, string sheetName, string connectionString)
        {
            DataSet ds = new DataSet();
            try
            {
                // 1. 讀取 Excel 資料
                string strConn = $"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={excelFile};Extended Properties=Excel 8.0;";
                using (OleDbConnection conn = new OleDbConnection(strConn))
                {
                    conn.Open();
                    string strExcel = $"select * from [{sheetName}$]";
                    OleDbDataAdapter myCommand = new OleDbDataAdapter(strExcel, strConn);
                    myCommand.Fill(ds, sheetName);
                }

                // 2. 若目標表不存在則建立(簡易版,實務建議預先建立結構)
                string strSql = $"if object_id('{sheetName}') is null create table {sheetName}(";
                foreach (DataColumn c in ds.Tables[0].Columns)
                {
                    strSql += $"[{c.ColumnName}] varchar(255),";
                }
                strSql = strSql.TrimEnd(',') + ")";

                using (SqlConnection sqlconn = new SqlConnection(connectionString))
                {
                    sqlconn.Open();
                    SqlCommand command = sqlconn.CreateCommand();
                    command.CommandText = strSql;
                    command.ExecuteNonQuery();
                }

                // 3. 使用 SqlBulkCopy 批量匯入
                using (SqlBulkCopy bcp = new SqlBulkCopy(connectionString))
                {
                    bcp.SqlRowsCopied += bcp_SqlRowsCopied;
                    bcp.BatchSize = 100;         // 每批筆數
                    bcp.NotifyAfter = 100;       // 進度通知間隔
                    bcp.DestinationTableName = sheetName;
                    bcp.WriteToServer(ds.Tables[0]);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        // 進度顯示
        void bcp_SqlRowsCopied(object sender, SqlRowsCopiedEventArgs e)
        {
            this.Text = e.RowsCopied.ToString();
            this.Update();
        }
    }
}

關鍵參數說明

  • BatchSize:每批次傳輸的資料列數,預設為 0(一次全傳)。設定適當值可減少記憶體壓力並啟用進度通知。
  • NotifyAfter:觸發 SqlRowsCopied 事件的間隔筆數,配合 UI 更新進度。
  • DestinationTableName:目標資料表名稱。
  • ColumnMappings:若 Excel 欄位順序/名稱與資料表不一致,需明確對應;否則依順序對應。

效能實測

測試環境:開發機、6 萬筆資料、單一工作表。
結果:含讀取 Excel 總耗時約 10 秒,純 SqlBulkCopy 匯入僅 4.5 秒。相較逐筆 INSERT 可提升數十倍效能。

進階建議

  1. 預先在資料庫建立目標表結構(含索引、約束),避免執行時動態建表。
  2. 使用 SqlBulkCopyOptions.TableLock 鎖定資料表以加速匯入(需獨佔存取)。
  3. 大量資料時考慮分批次、多執行緒平行匯入。
  4. 匯入前驗證資料型別、長度,避免轉換錯誤導致整批失敗。

結語

SqlBulkCopy 是 C# 大量寫入 SQL Server 的最佳利器。掌握其用法,能輕鬆應對百萬級資料匯入需求,大幅縮短 ETL 處理時間。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved