使用SqlBulkCopy大量復(fù)制文字文件(C#)

2010-08-28 10:50:44來(lái)源:西部e網(wǎng)作者:

我們?cè)谥暗囊黄恼拢?/SPAN>http://www.cnblogs.com/liminzhang/archive/2006/10/20/534471.html)提到如何使用 SqlBulkCopy 對(duì)象來(lái)大量復(fù)制文字文件,當(dāng)時(shí)所使用的程序語(yǔ)言是 Visual Basic 2005,有讀者希望提供 Visual C# 2005 的程序代碼。在此茲將程序代碼列示如下,請(qǐng)自行參考之:

 

// 匯入命名空間。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.VisualBasic.FileIO;

namespace VC測(cè)試項(xiàng)目
{
    public partial class Form4 : Form
    {
        public Form4()
        {
            InitializeComponent();
        }

        private string[] currentRow;
        private int myRowCount = 1;
        private int myBatchCount = 1;
        private long myCopiedRows = 0;
        private long countStart;

        // 建立「章立民研究室」數(shù)據(jù)表,此處是當(dāng)作一個(gè)中介數(shù)據(jù)表來(lái)使用。
        private DataTable myTable = new DataTable("章立民工作室");

        private void btnGoBulkCopy_Click(object sender, EventArgs e)
        {
            this.btnGoBulkCopy.Enabled = false;

            // 建立「員工編號(hào)」字段。
            DataColumn colEmployeeId =
                myTable.Columns.Add("員工編號(hào)", Type.GetType("System.Int32"));

            // 建立「身份證字號(hào)」字段。
            myTable.Columns.Add("身份證字號(hào)", Type.GetType("System.String"));
            myTable.Columns["身份證字號(hào)"].MaxLength = 10;
            myTable.Columns["身份證字號(hào)"].AllowDBNull = false;

            // 建立「姓名」字段。
            myTable.Columns.Add("姓名", Type.GetType("System.String"));
            myTable.Columns["姓名"].MaxLength = 12;

            // 建立「性別」字段。
            myTable.Columns.Add("性別", Type.GetType("System.String"));
            // myTable.Columns["性別"].MaxLength = 1;

            // 建立「地址」字段。
            myTable.Columns.Add("地址", Type.GetType("System.String"));
            myTable.Columns["地址"].MaxLength = 41;

            // 建立「郵政編碼」字段。
            myTable.Columns.Add("郵政編碼", Type.GetType("System.String"));
            myTable.Columns["郵政編碼"].MaxLength = 5;

            // 建立「出生日期」字段。
            myTable.Columns.Add("出生日期", Type.GetType("System.DateTime"));

            // 建立「婚姻狀況」字段。
            myTable.Columns.Add("婚姻狀況", Type.GetType("System.String"));

            // 建立「雇用日期」字段。
            myTable.Columns.Add("雇用日期", Type.GetType("System.DateTime"));

            // 建立「起薪」字段。
            myTable.Columns.Add("起薪", Type.GetType("System.Double"));

            // 建立「目前薪資」字段。
            myTable.Columns.Add("目前薪資", Type.GetType("System.Double"));

            // 建立「加薪日期」字段。
            myTable.Columns.Add("加薪日期", Type.GetType("System.DateTime"));

            // 建立「部門」字段。
            myTable.Columns.Add("部門", Type.GetType("System.String"));
            myTable.Columns["部門"].MaxLength = 10;

            using(TextFieldParser myReader = new TextFieldParser(@"Text\章立民工作室.txt"))
            {
                // 表示文件內(nèi)容是字符分隔。
                myReader.TextFieldType = FieldType.Delimited;

                // 定義文字文件的字符分隔符。
                myReader.Delimiters = new string[] {","};

                // 循環(huán)處理文字文件中所有數(shù)據(jù)列的所有字段。
                while(!myReader.EndOfData)
                {
                    try
                    {
                        currentRow = myReader.ReadFields();

                        // 略過(guò)標(biāo)題列
                        if(myRowCount > 1)

                       {
                            myTable.Rows.Add(currentRow);
                        }
                    }
                    catch(MalformedLineException ex)
                    {
                        MessageBox.Show(ex.Message);
                        return;
                    }

                    myRowCount += 1;
                    this.lblBeingCopyedTextRows.Text = myTable.Rows.Count.ToString();
                    this.lblBeingCopyedTextRows.Refresh();

                    if(myTable.Rows.Count == 50000)
                    {
                        try
                        {
                            GoBulkCopy();
                        }
                        catch(Exception ex)
                        {
                            MessageBox.Show(ex.Message);
                            return;
                        }

                        // 清空資料表。
                        myTable.Rows.Clear();
                        myBatchCount += 1;
                    }
                }

                // 復(fù)制最后一批不足50000 筆的數(shù)據(jù)記錄。
                if(myTable.Rows.Count > 0)
                {
                    GoBulkCopy();
                }
            }

            this.lblBeingCopyedTextRows.Text = myTable.Rows.Count.ToString();
            this.lblTextFileRowCount.Text =
              "來(lái)源文字文件的數(shù)據(jù)筆數(shù):" + (myRowCount - 2).ToString();
            this.btnGoBulkCopy.Enabled = true;
        }

        private void GoBulkCopy()
        {
            // 利用SqlConnectionStringBuilder 對(duì)象來(lái)構(gòu)建連接字符串。
            // 由于本范例是在同一個(gè)SQL Server 數(shù)據(jù)庫(kù)的不同數(shù)據(jù)表之間進(jìn)行大量復(fù)
            // 制作業(yè),因此連接至來(lái)源數(shù)據(jù)庫(kù)與連接至目標(biāo)服務(wù)器的連接字符串是相同的。
            SqlConnectionStringBuilder sqlconStringBuilder =
              new SqlConnectionStringBuilder();

            sqlconStringBuilder.DataSource = @"(local)\SQLExpress";
            sqlconStringBuilder.InitialCatalog = "北風(fēng)貿(mào)易";
            sqlconStringBuilder.IntegratedSecurity = true;

            // 建立連結(jié)至目標(biāo)SQL Server 數(shù)據(jù)庫(kù)的連接。
            using(SqlConnection con_bulkcopy =
              new SqlConnection(sqlconStringBuilder.ConnectionString))
            {
                // 開(kāi)啟連接至目標(biāo)SQL Server 的連接。
                con_bulkcopy.Open();

                SqlCommand cmdRowCount = new SqlCommand(
                  "SELECT COUNT(*) FROM dbo.Bulk_Target_章立民工作室;",
                  con_bulkcopy);

                if(myBatchCount == 1)
                {
                    // 計(jì)算出目標(biāo)數(shù)據(jù)表在執(zhí)行大量復(fù)制作業(yè)前有多少筆數(shù)據(jù)記錄。
                    countStart =
                      System.Convert.ToInt32(cmdRowCount.ExecuteScalar());
                    this.lblRowsCountBeforeBulkCopy.Text =
                      "目標(biāo)數(shù)據(jù)表在大量復(fù)制前擁有的數(shù)據(jù)筆數(shù)= " +
                      countStart.ToString();
                    this.lblRowsCountBeforeBulkCopy.Refresh();
                }

                // 建立一個(gè)SqlBulkCopy 對(duì)象以便執(zhí)行大量復(fù)制作業(yè)。
                using(SqlBulkCopy bcp = new SqlBulkCopy(con_bulkcopy))
                {
                    // 指定目標(biāo)數(shù)據(jù)表的名稱。
                    bcp.DestinationTableName = "dbo.Bulk_Target_章立民工作室";

                    // 如果來(lái)源數(shù)據(jù)表與目標(biāo)數(shù)據(jù)表的各個(gè)字段順序沒(méi)有完全對(duì)應(yīng),
                    // 必須在此設(shè)定來(lái)源字段與目標(biāo)字段的對(duì)應(yīng)關(guān)系。

                    // 將來(lái)源數(shù)據(jù)寫入目標(biāo)數(shù)據(jù)表。
                    bcp.WriteToServer(myTable);
                }

                // 最后再計(jì)算出大量復(fù)制了多少筆數(shù)據(jù)記錄。
                long countEnd =
                  System.Convert.ToInt32(cmdRowCount.ExecuteScalar());

                // 計(jì)算出累計(jì)復(fù)制筆數(shù)。
                myCopiedRows = countEnd - countStart;

                // 顯示出批次與大量復(fù)制累計(jì)筆數(shù)。
                this.DataGridView1.Rows.Add(
                  new string[] {
                  Convert.ToString(myBatchCount), Convert.ToString(myCopiedRows)});
                this.DataGridView1.Refresh();
            }
        }
    }
}

關(guān)鍵詞:C#