C#如何把百万级的excel数据导入到sqlserver数据库中去

想来大家都有这样的生活常识,一个正常人一顿能吃三个拳头大小的馒头,但是你让他一次性吃三百个馒头,那他撑不死我就表演胸口碎大石…
好了,我们言归正传,在我们处理一个有好几十万条数据的excel表格时,我们的电脑一般都会卡死,甚至会死机。这就是因为我们的数据量太大了,导致我们的计算机内存不足或者溢出(你的电脑只能吃三个馒头,你非让他吃三百个,它能受到了吗?)。所以我们一般的做法是把百万级的数据导入到数据库中去,然后用数据库做处理。可是现在问题来了,我们如何把几百万条数据直接导入到数据库里面去?
常规的Excel数据导入数据库的方法,博主这里就不赘述了,但是常规的方法都有一个绕不过去的坎,就是内存溢出的问题,因为无论前面的步骤如何不同,到最后都是要一次性读取数据,然后就是程序崩溃,电脑卡死的结果。这里我为大家提供一个新的思路,可以用来将百万级的excel数据导入到sqlserver数据库中去。这个思路的核心思想就是分批导入数据+SqlBulkCopy工具
我们的电脑毕竟不是真正的人,它虽然一次性无法吃掉三百个馒头,但是它的“消化功能”非常的好,它吃完三个馒头后就可以立马在吃三个馒头,就这样,我一次吃三个,我吃一百次,我三百个馒头也就吃完了。同样,我一次只导入一万条数据,我一百次就能导入一百万条数据!好了原理就阐述到这里,接下来我们看一下代码部分:

    public void TransferData(string excelFile,  string connectionString)
        {

            //   try
            {
                string strConn = "";
                //获取全部数据   
                FileInfo file = new FileInfo(excelFile);
                if (!file.Exists) { throw new Exception("文件不存在"); }
                string extension = file.Extension;
                if (extension == ".xls")
                    strConn = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 8.0;HDR=Yes;IMEX=1;'", excelFile);
                if (extension == ".xlsx")
                    strConn = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0;HDR=Yes;IMEX=1;'", excelFile);
                if (strConn == "") { throw new Exception("excel版本过低,请更换成Office2007以上版本"); }
                OleDbConnection conn = new OleDbConnection(strConn);
                conn.Open();
                string strExcel = "";
                DataTable table = conn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null);
                string tableName = table.Rows[0]["Table_Name"].ToString();//自动读取excel第一个表的表名
                string sheetName;
                sheetName = tableName.Substring(0, tableName.Length - 1);
                string strExcel_Num = string.Format(@"select count(*) from [{0}$]", sheetName);
                OleDbDataAdapter myCommand_Num = new OleDbDataAdapter(strExcel_Num, strConn);
                DataSet ds_CloNum = new DataSet();
                myCommand_Num.Fill(ds_CloNum, sheetName);
                int RowNum = (int)ds_CloNum.Tables[0].Rows[0].ItemArray[0];//获取excel中的总行数
                int stat = 0;
                int end = 10000;
                double loopTimes = Math.Ceiling(Convert.ToDouble(RowNum * 1.0 / 10000));//控制循环次数,向上取整
                for (int i = 0; i < loopTimes; i++)
                {
                    strExcel = string.Format(@"select * from [{0}$] where  id >={1} and id <{2}", sheetName, stat, end);//表格中需要加一列id,是自动排序的,用来分割数据,如果用access语句在查询结果上加个序号列也行
                    stat = stat + 10000;
                    end = end + 10000;
                    OleDbDataAdapter myCommand = new OleDbDataAdapter(strExcel, strConn);
                    DataSet ds = new DataSet();
                    myCommand.Fill(ds, sheetName);
                    //如果目标表不存在则创建   
                    string strSql = string.Format("if object_id('{0}') is null create table {0}(", sheetName);
                    foreach (System.Data.DataColumn c in ds.Tables[0].Columns)
                    {
                        strSql += string.Format("[{0}] varchar(1000),", c.ColumnName);
                    }
                    strSql = strSql.Trim(',') + ")";
                    using (System.Data.SqlClient.SqlConnection sqlconn = new System.Data.SqlClient.SqlConnection(connectionString))
                    {
                        sqlconn.Open();
                        System.Data.SqlClient.SqlCommand command = sqlconn.CreateCommand();
                        command.CommandText = strSql;
                        command.ExecuteNonQuery();
                        sqlconn.Close();
                    }
                    //用bcp导入数据   
                    using (System.Data.SqlClient.SqlBulkCopy bcp = new System.Data.SqlClient.SqlBulkCopy(connectionString))
                    {
                        bcp.SqlRowsCopied += new System.Data.SqlClient.SqlRowsCopiedEventHandler(bcp_SqlRowsCopied);
                        bcp.BatchSize = 100;//每次传输的行数   
                        bcp.NotifyAfter = 100;//进度提示的行数   
                        bcp.DestinationTableName = sheetName;//目标表   
                        bcp.WriteToServer(ds.Tables[0]);
                    }
                }


                MessageBox.Show("导入成功");
            }
            //  catch (Exception ex)
            {
                //  System.Windows.Forms.MessageBox.Show(ex.Message);
            }


        }

        //进度显示   
        void bcp_SqlRowsCopied(object sender, System.Data.SqlClient.SqlRowsCopiedEventArgs e)
        {
            this.Text = e.RowsCopied.ToString();
            this.Update();
        }

代码大家可以拿去直接用,博主测试了一下40万条数据插入数据库用时三分钟左右。博主逛博客多年,遇到问题总是能在博客找到思路或者答案,在这里首先对这些前辈表示感谢!前人栽树后人乘凉,希望有更多的人能将自己遇到的问题和解决方案共享出来,大家共同进步。赠人玫瑰,手有余香,也祝各位在2020年白白胖胖,充满希望~

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是C# WinForm中将Excel数据导入SQL Server数据库中的步骤: 1. 需要添加对Microsoft.Office.Interop.Excel和System.Data.SqlClient的引用。 2. 建立一个Windows Form应用程序,并在表单上添加一个按钮,用于触发导入Excel数据的过程。 3. 在按钮的Click事件中编写代码,打开Excel文件并读取数据。 ```csharp using Excel = Microsoft.Office.Interop.Excel; Excel.Application excelApp = new Excel.Application(); Excel.Workbook workbook = excelApp.Workbooks.Open(@"C:\example.xlsx"); Excel.Worksheet worksheet = workbook.Sheets[1]; int rowsCount = worksheet.UsedRange.Rows.Count; int columnsCount = worksheet.UsedRange.Columns.Count; for (int row = 1; row <= rowsCount; row++) { for (int col = 1; col <= columnsCount; col++) { string cellValue = (worksheet.Cells[row, col] as Excel.Range).Value.ToString(); // Do something with the cell value } } workbook.Close(); excelApp.Quit(); ``` 4. 创建一个SqlConnection对象,用于连接到SQL Server数据库。 ```csharp using System.Data.SqlClient; SqlConnection connection = new SqlConnection("Data Source=serverName;Initial Catalog=databaseName;Integrated Security=True"); connection.Open(); ``` 5. 创建一个SqlCommand对象,用于执行插入语句。 ```csharp SqlCommand command = new SqlCommand("INSERT INTO TableName (Column1, Column2) VALUES (@Value1, @Value2)", connection); command.Parameters.AddWithValue("@Value1", cellValue1); command.Parameters.AddWithValue("@Value2", cellValue2); command.ExecuteNonQuery(); ``` 6. 在循环中使用SqlCommand对象插入数据。 7. 关闭SqlConnection对象。 ```csharp connection.Close(); ``` 完成以上步骤后,您的C# WinForm应用程序就能够将Excel数据导入SQL Server数据库中了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值