zoukankan      html  css  js  c++  java
  • C# SqlBulkCopy数据批量入库

    准备条件:20万+数据

    界面设计使用的WPF。

    没有对比就没有伤害,以下是我两种方式导入数据案例。

    运行 结果对比:

    首先使用一般sql语句导入,因为时间原因,我就没有等待程序执行完,但是我记录了大约需要多少时间,以及执行了多少时间。
    导入数据共计:258113条,执行了38秒,已经入库了6971条,大约还需要1429秒。(不去考虑电脑配置,界面数据加载耗时等因素)

    接下来我们看看同样的数据量 SqlBulkCopy效果如何:

    当我注释代码中使用异步操作,当然,界面会出现假死状态。再来看看运行结果。

     

    解析数据时间明显减少。

    以下是这个测试工具的全部代码:

        /// <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:UsersWenDaoJunDocumentsVisual Studio 2015ProjectsJWellJWell.Cloud.UIResourcesTxt";
                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++)
                    {
                        // 拼接数据
                        // 解析文本文件  ""号段"	"所属地区"	"号码类型"	"区号"" 
                        var strs = lines[i].Split('	');
                        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();
                    // 拼接数据
                    // 解析文本文件  ""号段"	"所属地区"	"号码类型"	"区号"" 
                    var strs = lines[i].Split('	');
                    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; });
    
            }
        }
  • 相关阅读:
    Python Scrapy爬虫(下)
    Hadoop HDFS
    Spark核心 RDD(上)
    自定义日期格式------SimpleDateFormat
    常用类-- 使用comparator实现定制排序
    自定义日期格式------DateTimeFormatter
    多线程-方式四使用线程池
    多线程-方式三实现Callable接口方式 JDK5.0新增
    解决线程安全------lock锁
    死锁问题
  • 原文地址:https://www.cnblogs.com/wendj/p/9015018.html
Copyright © 2011-2022 走看看