C# SqlBulkCopy數據批量入庫

準備條件:20萬+數據sql

界面設計使用的WPF。數據庫

沒有對比就沒有傷害,如下是我兩種方式導入數據案例。app

運行 結果對比:異步

首先使用通常sql語句導入,由於時間緣由,我就沒有等待程序執行完,可是我記錄了大約須要多少時間,以及執行了多少時間。
導入數據共計:258113條,執行了38秒,已經入庫了6971條,大約還須要1429秒。(不去考慮電腦配置,界面數據加載耗時等因素)工具

接下來咱們看看一樣的數據量 SqlBulkCopy效果如何:測試

當我註釋代碼中使用異步操做,固然,界面會出現假死狀態。再來看看運行結果。ui

 

 

解析數據時間明顯減小。this

 

如下是這個測試工具的所有代碼:spa

    /// <summary>
    /// BatchImportForm.xaml 的交互邏輯
    /// </summary>
    public partial class BatchImportForm : Window
    { 
        private static readonly string ConnStr = ConfigurationManager.ConnectionStrings["myconnStr"].ConnectionString;
        public BatchImportForm()
        {
            InitializeComponent();
        }

        private void BtnQueryImport_Click(object sender, RoutedEventArgs e)
        {
            var filePath = GetFilePath();
            if (!string.IsNullOrEmpty(filePath))
            {
                // 防止界面假死狀態
                Task task = Task.Factory.StartNew(() =>
                {
                    SqlWork(filePath);
                });
            }
        }

        private string GetFilePath()
        {
            // 讀取文本文件
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = System.Environment.CurrentDirectory+ "\\Resources\\Txt"; // @"C:\Users\WenDaoJun\Documents\Visual Studio 2015\Projects\JWell\JWell.Cloud.UI\Resources\Txt";
            ofd.Title = "讀取文件";
            ofd.FileName = "";
            ofd.RestoreDirectory = true;
            ofd.Filter = "全部文件(*.*)|*.*|文本文件(*.txt)|*.txt";
            ofd.ValidateNames = true;
            ofd.CheckFileExists = true;
            ofd.CheckPathExists = true;
            string strName = string.Empty;
            if (ofd.ShowDialog() == true)
            {
                strName = ofd.FileName;
            }
            if (strName == "")
            {
                MessageBox.Show("沒有選擇文件!");
                return null;
            }
            return strName;
        }
         
        private void BtnQueryImportTwo_Click(object sender, RoutedEventArgs e)
        {
            string filePath = GetFilePath();
            //if (!string.IsNullOrEmpty(filePath))
            //{
            //    Task task = Task.Factory.StartNew(() =>
            //      {
            //          SqlBulkWord(filePath);
            //      });

            //}
             SqlBulkWord(filePath);
        }
      
        
        /// <summary>
        /// 第一種方法
        /// </summary>
        /// <param name="fuillPath"></param>
        private void SqlWork(string fuillPath)
        {
            var lines = File.ReadAllLines(fuillPath, Encoding.Default);
            // 異步給控件賦值
            this.Dispatcher.Invoke(() => { this.JingDuOn.Maximum = lines.Length; });
            this.Dispatcher.Invoke(() => { this.LblRuKuOne.Content = lines.Length; });
            using (SqlConnection conn = new SqlConnection(ConnStr))
            {
                conn.Open();
                var t1 = DateTime.Now;
                for (int i = 0; i < lines.Length; i++)
                {
                    // 拼接數據
                    // 解析文本文件  "\"號段\"\t\"所屬地區\"\t\"號碼類型\"\t\"區號\"" 
                    var strs = lines[i].Split('\t');
                    var telNumber = strs[0].Trim('"');
                    var telArea = strs[1].Trim('"');
                    var telType = strs[2].Trim('"');
                    var telAreaCode = strs[3].Trim('"');
                    // 入庫
                    using (SqlCommand cmd = conn.CreateCommand())
                    {
                        cmd.CommandText = @"insert into TelNum(TelNumber,TelType,TelArea,TelAreaCode) values(@TelNumber,@TelType,@TelArea,@TelAreaCode)";
                        cmd.Parameters.Add(new SqlParameter("@TelNumber", telNumber));
                        cmd.Parameters.Add(new SqlParameter("@TelType", telArea));
                        cmd.Parameters.Add(new SqlParameter("@TelArea", telType));
                        cmd.Parameters.Add(new SqlParameter("@TelAreaCode", telAreaCode));
                        cmd.ExecuteNonQuery();
                        //異步委託 
                        this.JingDuOn.Dispatcher.Invoke(() => { this.JingDuOn.Value += 1; });
                        this.LblJinDuOne.Dispatcher.Invoke(() => { this.LblJinDuOne.Content = i; });
                    }
                    var t2 = DateTime.Now;
                    var tsp = t2 - t1;
                    // 異步給控件賦值
                    this.LblHaoShiOne.Dispatcher.Invoke(() => { this.LblHaoShiOne.Content = tsp.TotalSeconds; });
                    this.LblZongHaoShiOne.Dispatcher.Invoke(() => { this.LblZongHaoShiOne.Content = $"倒計時{(tsp.TotalSeconds * lines.Length / (i + 1))}秒完成。"; });
                }

            }
        }

        /// <summary>
        /// 第二種方法
        /// </summary>
        /// <param name="filePath"></param>
        private void SqlBulkWord(string filePath)
        {
            var lines = File.ReadAllLines(filePath, Encoding.Default);
            this.Dispatcher.Invoke(() => { this.JingDuTwo.Maximum = lines.Length; });
            this.Dispatcher.Invoke(() => { this.LblRuKuTwo.Content = lines.Length; });
            var t1 = DateTime.Now;

            // 建立入庫須要的數據源 DataTable
            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("TelNumber", typeof(string)));
            dt.Columns.Add(new DataColumn("TelType", typeof(string)));
            dt.Columns.Add(new DataColumn("TelArea", typeof(string)));
            dt.Columns.Add(new DataColumn("TelAreaCode", typeof(string)));
             
            for (int i = 0; i < lines.Length; i++)
            {
                var row = dt.NewRow();
                // 拼接數據
                // 解析文本文件  "\"號段\"\t\"所屬地區\"\t\"號碼類型\"\t\"區號\"" 
                var strs = lines[i].Split('\t');
                row["TelNumber"] = strs[0].Trim('"');
                row["TelType"] = strs[1].Trim('"');
                row["TelArea"] = strs[2].Trim('"');
                row["TelAreaCode"] = strs[3].Trim('"');
                dt.Rows.Add(row);

                this.JingDuTwo.Dispatcher.Invoke(() => { this.JingDuTwo.Value += 1; });
                this.LblJinDuTwo.Dispatcher.Invoke(() => { this.LblJinDuTwo.Content = i; });

            }
            var t2 = DateTime.Now;
            var tsp = t2 - t1;
            this.LblHaoShiTwo.Dispatcher.Invoke(() => { this.LblHaoShiTwo.Content = tsp.TotalSeconds; });


            // 入庫計時
            var sw = new Stopwatch();
            sw.Start(); 
            using (SqlBulkCopy sbk = new SqlBulkCopy(ConnStr))
            {
                //表名
                sbk.DestinationTableName = "TelNum";
                //DataTable中的列名和數據庫中列名對應
                sbk.ColumnMappings.Add("TelNumber", "TelNumber");
                sbk.ColumnMappings.Add("TelType", "TelType");
                sbk.ColumnMappings.Add("TelArea", "TelArea");
                sbk.ColumnMappings.Add("TelAreaCode", "TelAreaCode");
                sbk.WriteToServer(dt);
            }
            sw.Stop();
        
         this.LblZongHaoShiTwo.Dispatcher.Invoke(() => { this.LblZongHaoShiTwo.Content=sw.Elapsed.TotalSeconds; });

        }
    }
相關文章
相關標籤/搜索