侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

sql下三种批量插入数据的方法

数据库  /  管理员 发布于 5年前   308

本文将介绍三种批量插入数据的方法。第一种方法是使用循环语句逐个将数据项插入到数据库中;第二种方法使用的是SqlBulkCopy,使您可以用其他源的数据有效批量加载 SQL Server 表;第三种使用的方法是sql server中的表值参数方法,表值参数是 SQL Server 2008 中的新参数类型。表值参数是使用用户定义的表类型来声明的。使用表值参数,可以不必创建临时表或许多参数,即可向 Transact-SQL 语句或例程(如存储过程或函数)发送多行数据。

      代码示例:

      此例子为控制台输出程序,有两个类,一个为BulkData类,主要实现了表值参数和sqlbulkcopy是如何插入数据的,一个类为Repository,一个app.config配置文件。所用数据库为sql server 2012。

       建库语句:

复制代码 代码如下:
打开
--Create DataBase
use master
go
if exists(select * from master.sys.sysdatabases where name=N'BulkDB')
drop database BulkDB
create database BulkDB;
go


--Create Table
use BulkDB
go

if exists(select * from sys.objects where object_id=OBJECT_ID(N'[dbo].[BulkTable]') and type in(N'U'))
drop table [dbo].BulkTable
Create table BulkTable(
Id int primary key,
UserName nvarchar(32),
Pwd varchar(16))
go


--Create Table Valued
use BulkDB
go

if exists
(
select * from sys.types st
join sys.schemas ss
on st.schema_id=ss.schema_id
where st.name=N'[BulkType]' and ss.name=N'dbo'
)
drop type [dbo].[BulkType]
go

create type [dbo].[BulkType] as table
  (
   Id int,
   UserName nvarchar(32),
   Pwd varchar(16)
   )
go

select * from dbo.BulkTable

BulkData.cs

复制代码 代码如下:
打开
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

namespace BulkData
{
    class BulkData
    {
        public static void TableValuedToDB(DataTable dt)
        {
            SqlConnection sqlConn = new SqlConnection(
              ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString);
            const string TSqlStatement =
             "insert into BulkTable (Id,UserName,Pwd)" +
             " SELECT nc.Id, nc.UserName,nc.Pwd" +
             " FROM @NewBulkTestTvp AS nc";
            SqlCommand cmd = new SqlCommand(TSqlStatement, sqlConn);
            SqlParameter catParam = cmd.Parameters.AddWithValue("@NewBulkTestTvp", dt);

            catParam.SqlDbType = SqlDbType.Structured;

            catParam.TypeName = "dbo.BulkType";
            try
            {
                sqlConn.Open();
                if (dt != null && dt.Rows.Count != 0)
                {
                    cmd.ExecuteNonQuery();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                sqlConn.Close();
            }
        }

        public static DataTable GetTable()
        {
            DataTable dt = new DataTable();

            dt.Columns.AddRange(new DataColumn[]{new DataColumn("Id",typeof(int)),new DataColumn("UserName",typeof(string)),new DataColumn("Pwd",typeof(string))});

            return dt;
        }

        public static void BulkToDB(DataTable dt)
        {
            SqlConnection sqlConn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString);
            SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConn);
            bulkCopy.DestinationTableName = "BulkTable";
            bulkCopy.BatchSize = dt.Rows.Count;

            try
            {
                sqlConn.Open();
                if (dt != null && dt.Rows.Count != 0)
                    bulkCopy.WriteToServer(dt);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                sqlConn.Close();
                if (bulkCopy != null)
                    bulkCopy.Close();
            }
        }
    }
}

Repository.cs

复制代码 代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Diagnostics;

namespace BulkData
{
    public class Repository
    {
        public static void UseSqlBulkCopyClass()
        {
            Stopwatch sw = new Stopwatch();
            for (int outLayer = 0; outLayer < 10; outLayer++)
            {
                DataTable dt = BulkData.GetTable();
                for (int count = outLayer * 100000; count < (outLayer + 1) * 100000; count++)
                {
                    DataRow r = dt.NewRow();
                    r[0] = count;
                    r[1] = string.Format("User-{0}", count * outLayer);
                    r[2] = string.Format("Password-{0}", count * outLayer);
                    dt.Rows.Add(r);
                }
                sw.Start();
                BulkData.BulkToDB(dt);
                sw.Stop();
                Console.WriteLine(string.Format("{1} hundred thousand data elapsed Time is {0} Milliseconds", sw.ElapsedMilliseconds, outLayer + 1));
            }

            Console.ReadLine();
        }

        public static void UseTableValue()
        {
            Stopwatch sw = new Stopwatch();

            for (int outLayer = 0; outLayer < 10; outLayer++)
            {
                DataTable dt = BulkData.GetTable();

                for (int count = outLayer * 100000; count < (outLayer + 1) * 100000; count++)
                {
                    DataRow dataRow = dt.NewRow();
                    dataRow[0] = count;
                    dataRow[1] = string.Format("User-{0}", count * outLayer);
                    dataRow[2] = string.Format("Password-{0}", count * outLayer);
                    dt.Rows.Add(dataRow);
                }

                sw.Start();
                BulkData.TableValuedToDB(dt);
                sw.Stop();

                Console.WriteLine(string.Format("{1} hundred thousand data elapsed Time is {0} Milliseconds", sw.ElapsedMilliseconds, outLayer + 1));
            }

            Console.ReadLine();
        }

        public static void UserNormalInsert()
        {
            Stopwatch sw = new Stopwatch();

            SqlConnection sqlConn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString);

            SqlCommand sqlComm = new SqlCommand();
            sqlComm.CommandText = string.Format("insert into BulkTable(Id,UserName,Pwd)values(@p0,@p1,@p2)");
            sqlComm.Parameters.Add("@p0", SqlDbType.Int);
            sqlComm.Parameters.Add("@p1", SqlDbType.NVarChar);
            sqlComm.Parameters.Add("@p2", SqlDbType.VarChar);
            sqlComm.CommandType = CommandType.Text;
            sqlComm.Connection = sqlConn;
            sqlConn.Open();

            try
            {
                for (int outLayer = 0; outLayer < 10; outLayer++)
                {
                    for (int count = outLayer * 100000; count < (outLayer + 1) * 100000; count++)
                    {

                        sqlComm.Parameters["@p0"].Value = count;
                        sqlComm.Parameters["@p1"].Value = string.Format("User-{0}", count * outLayer);
                        sqlComm.Parameters["@p2"].Value = string.Format("Password-{0}", count * outLayer);
                        sw.Start();
                        sqlComm.ExecuteNonQuery();
                        sw.Stop();
                    }

                    Console.WriteLine(string.Format("{1} hundred thousand data elapsed Time is {0} Milliseconds", sw.ElapsedMilliseconds, outLayer + 1));
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                sqlConn.Close();
            }

            Console.ReadLine();
        }
    }
}

App.config

复制代码 代码如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="ConnStr"
      connectionString="data source=.;Integrated Security=SSPI;Initial Catalog=BulkDB"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

 Program.cs

复制代码 代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Diagnostics;

namespace BulkData
{
    class Program
    {           
        static void Main(string[] args)
        {
            //Repository.UseSqlBulkCopyClass();
            Repository.UseTableValue();
            //Repository.UserNormalInsert();
        }       
    }
}


三种方法分别插入100万条数据所用的时间为:

       循环语句所用时间:

      

        sqlbulkcopy方法所用时间为:

       

         表值参数所用时间为:

        

我不会告诉你有一种sql语法可以这么写:

复制代码 代码如下:
insert into SystemSet_tbl (ss_guid,ss_type,ss_comment) values ('00000000-0000-0000-0000-000000000007',1,''),('00000000-0000-0000-0000-000000000008',1,'')


  • 上一条:
    SQL查询中in和exists的区别分析
    下一条:
    SQL分页语句的三种方案
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 分库分表的目的、优缺点及具体实现方式介绍(0个评论)
    • DevDB - 在 VS 代码中直接访问数据库(0个评论)
    • 在ubuntu系统中实现mysql数据存储目录迁移流程步骤(0个评论)
    • 在mysql中使用存储过程批量新增测试数据流程步骤(0个评论)
    • php+mysql数据库批量根据条件快速更新、连表更新sql实现(0个评论)
    • 近期文章
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2017-06
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-01
    • 2018-05
    • 2018-10
    • 2018-11
    • 2020-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2021-02
    • 2021-04
    • 2021-07
    • 2021-08
    • 2021-11
    • 2021-12
    • 2022-02
    • 2022-03
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-07
    • 2023-08
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-03
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客