zoukankan      html  css  js  c++  java
  • C# 使用SqlBulkCopy类批量复制大数据

    用途说明:

    前些日子,公司要求做一个数据导入程序,要求将Excel数据,大批量的导入到数据库中,尽量少的访问数据库,高性能的对数据库进行存储。于是在网上进行查找,发现了一个比较好的解决方案,就是采用SqlBulkCopy来处理存储数据。SqlBulkCopy存储大批量的数据非常的高效,就像这个方法的名字一样,可以将内存中的数据表直接的一次性的存储到数据库中,而不需要一次一次的向数据库Insert数据。初次实验,百万级别的数据表,也只需几秒时间内就可以完全的存入数据库中,其速度,比传统的Insert方法不止快很多倍


           MSDN摘要:Microsoft SQL Server 提供一个称为 bcp 的流行的命令提示符实用工具,用于将数据从一个表移动到另一个表(表既可以在同一个服务器上,也可以在不同服务器上)。SqlBulkCopy 类允许编写提供类似功能的托管代码解决方案。还有其他将数据加载到 SQL Server 表的方法(例如 INSERT 语句),但相比之下 SqlBulkCopy 提供明显的性能优势。

    使用 SqlBulkCopy 类只能向 SQL Server 表写入数据。但是,数据源不限于 SQL Server;可以使用任何数据源,只要数据可加载到 DataTable 实例或可使用IDataReader 实例读取数据。

    复制代码
      /// <summary>
            /// 
            /// </summary>
            /// <param name="connectionString">目标连接字符</param>
            /// <param name="TableName">目标表</param>
            /// <param name="dt">源数据</param>
            private void SqlBulkCopyByDatatable(string connectionString, string TableName, DataTable dt)
            {
                using (SqlConnection conn = new SqlConnection(connectionString))
                {
                    using (SqlBulkCopy sqlbulkcopy =new SqlBulkCopy(connectionString, SqlBulkCopyOptions.UseInternalTransaction))
                    {
                        try
                        {
                            sqlbulkcopy.DestinationTableName = TableName;
                            for (int i = 0; i < dt.Columns.Count; i++)
                            {
                                sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName);
                            }
                            sqlbulkcopy.WriteToServer(dt);
                        }
                        catch (System.Exception ex)
                        {
                            throw ex;
                        }
                    }
                }
            }
    复制代码
    复制代码
     SqlBulkCopy使用使用用于自定义表类型作为存储过程参数,批量写入数据。
     
      如果,大家使用SQL Server 2008,它提供一个新的功能表变量(Table Parameters)可以将整个表数据汇集成一个参数传递给存储过程或SQL语句。它的注意性能开销是将数据汇集成参数(O(数据量))。
     
      现在,我们修改之前的代码,在SQL Server中定义我们的表变量,具体定义如下:
     -- =============================================
    -- Author:        JKhuang
    -- Create date: 08/16/2012
    -- Description:    Declares a user table paramter.
    -- =============================================
    CREATE TYPE jk_users_bulk_insert AS TABLE (
        user_login varchar(60),
        user_pass varchar(64),
        user_nicename varchar(50),
        user_email varchar(100),
        user_url varchar(100),
        user_activation_key varchar(60),
        user_status int,
        display_name varchar(250)
    )
     
      上面,我们定义了一个表参数jk_users_bulk_insert,接着我们定义一个存储过程接受表参数jk_users_bulk_insert,具体定义如下:
     -- =============================================
    -- Author:        JKhuang
    -- Create date: 08/16/2012
    -- Description:    Creates a stored procedure, receive
    -- a jk_users_bulk_insert argument.
    -- =============================================
    CREATE PROCEDURE sp_insert_jk_users 
    @usersTable jk_users_bulk_insert READONLY 
    AS
    INSERT INTO jk_users (user_login, user_pass, user_nicename, user_email, user_url, 
    user_activation_key, user_status, display_name, user_registered) 
    SELECT user_login, user_pass, user_nicename, user_email, user_url, 
    user_activation_key, user_status, display_name, GETDATE() 
    FROM @usersTable 
      接下我们在客户端代码中,调用存储过程并且将表作为参数方式传递给存储过程。
     var sw = Stopwatch.StartNew();
    using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLCONN2"].ToString()))
    {
        conn.Open();
        //// Invokes the stored procedure.
        using (var cmd = new SqlCommand("sp_insert_jk_users", conn))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            //// Adding a "structured" parameter allows you to insert tons of data with low overhead
            var param = new SqlParameter("@userTable", SqlDbType.Structured) { Value = dt };
            cmd.Parameters.Add(param);
            cmd.ExecuteNonQuery();
        }
    }
    sw.Stop(); 
      现在,我们重新执行写入操作发现写入效率与SqlBulkCopy相当。
    复制代码

    ///批量插入实例------------------------------------------------------------个人案例
    using System; using System.Collections.Generic; using System.Data; using System.Data.Entity; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Impoort { class Program { public static PQMEntities db = new PQMEntities(); static void Main(string[] args) { var users = db.Database.SqlQueryForDataTatable("select * from Right_Users", null); SqlBulkCopyByDatatable(db.Database.Connection.ConnectionString, "Right_UserTemp", users); } private static void SqlBulkCopyByDatatable(string connectionString, string TableName, DataTable dt) { using (SqlConnection conn = new SqlConnection()) { using (SqlBulkCopy sqlbulkcopy = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.UseInternalTransaction)) { try { sqlbulkcopy.DestinationTableName = TableName; for (int i = 0; i < dt.Columns.Count; i++) { sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName); } sqlbulkcopy.WriteToServer(dt); } catch (System.Exception ex) { throw ex; } } } } } public static class a { public static DataTable SqlQueryForDataTatable(this Database db, string sql, SqlParameter[] parameters) { SqlConnection conn = new System.Data.SqlClient.SqlConnection(); conn.ConnectionString = db.Connection.ConnectionString; if (conn.State != ConnectionState.Open) { conn.Open(); } SqlCommand cmd = new SqlCommand(); cmd.Connection = conn; cmd.CommandText = sql; if (parameters!=null&&parameters.Length > 0) { foreach (var item in parameters) { cmd.Parameters.Add(item); } } SqlDataAdapter adapter = new SqlDataAdapter(cmd); DataTable table = new DataTable(); adapter.Fill(table); return table; } } }

      

  • 相关阅读:
    topcoder srm 445 div1
    topcoder srm 440 div1
    topcoder srm 435 div1
    topcoder srm 430 div1
    topcoder srm 400 div1
    topcoder srm 380 div1
    topcoder srm 370 div1
    topcoder srm 425 div1
    WKWebView强大的新特性
    Runtime那些事
  • 原文地址:https://www.cnblogs.com/zengpeng/p/5806778.html
Copyright © 2011-2022 走看看