浙江恒生长运网络科技有限公司 苟安廷

用C#开发时,经常会配套使用Sql Server数据库,也经常希望将DataTable中的数据直接插入的数据库表中,但Sql Server数据库中并没有DataTable这种数据类型,要实现这个目的,最直观的方法就是拼Sql语句比如:

Insert into 数据库表(字段1,字段2….字段n)

Select ‘C1’,’C2’…’Cn’

union all

Select ‘C1’,’C2’…’Cn’

……

也可以写个通用方法,将DataTable转换成XML格式的字符串,然后通过值类型参数(nvarchar(max))将xml传递到数据中,在数据库里面还原成临时表,经二次加工后再插入到正式表。

以上两种方法都不方便,而且效率不高。

说到这里,大家都马上想到了更专业的方法:利用SqlBulkCopy,操作简便,更关键的是性能杠杠的,经本人实测,插入4000多条记录时,速度比xml方式快15倍以上。但SqlBulkCopy也有其致命弱点,那就用途单一,只能用来插入数据,其他的简单sql操作都进行不了,比如创建临时表、做一些简单计算、调用存储过程等,因此,如果将SqlBulkCopy和普通Sql操作结合起来就完美了,我们的设想业务逻辑顺序是这样的:

  1. 在软件里面准备准备好多个DataTable,这些存放了业务相关数据,可能需要插入正式表,也会做进一步加工
  2. 在数据库里面创建临时表,用于存放DataTable中的数据
  3. 用SqlBulkCopy将DataTable中的数据发到数据库临时表中
  4. 在数据库中进行必要的处理,并更新到正式表

由于临时表在断开连接后,就会被自动释放(关于临时表的生命周期请参考相关资料,简单说,断开后自动删除、同一个连接内可以共享),没办法和SqlBulkCopy “共享”,正因为临时表是连接断开后才会被自动释放的,因此,最自然的方式就是连接先不要断开,而是和SqlBulkCopy共享一个连接,那么,问题自然而然就解决了。

测试流程如下:

  1. 我们在数据库中准备一张表:

CREATE TABLE 测试表(UserName NVARCHAR(50),Age INT)

  1. 软件里面定义一个DataTable,结构和测试表完全一样,并模拟100条数据

如果字段名不一样,需要通过映射关系进行对应: sqlBulkCopy.ColumnMappings.Add(DataTable中的字段名,数据库表中的字段名))

  1. 创建共享连接
  2. 通过普通sql语句,创建临时表结构,注意,where 1=2永远不成立,故只会创建一个空的临时表,和正式表结构完全一样
  3. 通过SqlBulkCopy把数据传到临时表中
  4. 在数据库中,进行二次加工,最后更新到正式库
  5. 关闭连接

完整代码如下:

//1.模拟数据,注意表结构

var tb=new DataTable();

tb.Columns.Add("UserName", typeof(string));

tb.Columns.Add("Age", typeof(int));

for (var i = 0; i < 1000; i++)

tb.Rows.Add($"姓名:{i}", 10 + i);

//2.创建连接,供普通Sql操作和SqlBulkCopy共享,为简化代码,异常就不捕获了,实际生产时必须处理异常

var connection = new SqlConnection(_connStr);

connection.Open();

//3.根据正式表复制临时表结构,注意where语句,可以一次性创建多个临时表

var strSql = "select * into #temp from 测试表 WHERE 1=2";

var command=new SqlCommand(strSql,connection);

command.ExecuteNonQuery();

//4.传输数据,可以重复执行,将每种业务数据都写入临时表

var sqlBulkCopy = new SqlBulkCopy(connection)

{

DestinationTableName = "#temp",//目标表是临时表,而不是正式表

BatchSize=tb.Rows.Count

};

sqlBulkCopy.WriteToServer(tb);

//5.进行二次加工,当然,也可以调用存储过程(存储过程内部仍然可以使用刚才创建的临时表,注意,不要和存储过程自己定义的临时表重名了),比如,command.CommandText = "Exec myProcess @Name='张三'";

command.CommandText = "insert into 测试表 select * from #temp";

command.ExecuteNonQuery();

//6.最后关闭连接

connection.Close();

说白了,本的核心就是共享数据库连接,间接实现普通Sql操作和SqlBulkCopy协同,发挥各自的长处。

SqlBulkCopy与临时表、普通Sql操作配合使用相关推荐

  1. Hive基本SQL操作

    Hive基本SQL操作 库的创建与删除 建库语句 删除库 修改 表的建删改查 建表语句的结构 表相关的SQL语句 建表语句 创建普通表 创建字段限制的表 创建hive表 create like语法 创 ...

  2. SQL操作语句之查询及删除重复记录的方法

    delete from 表 where id not in(select min(id) from 表 group by name ) //删除重复名字的记录 删除之前请用语句 select * fr ...

  3. Oracle临时表和SQL Server临时表的不同点对比

    文章来源:http://www.codesky.net/article/201109/141401.html 1.简介 Oracle数据库除了可以保存永久表外,还可以建立临时表temporary ta ...

  4. Spark SQL操作多数据源

    Spark SQL支持通过DataFrame接口操作的多种不同的数据源.DataFrame提供支持统一的接口加载和保存数据源中的数据,包括:结构化数据,Parquet文件,JSON文件,Hive表 , ...

  5. Spark15:Spark SQL:DataFrame常见算子操作、DataFrame的sql操作、RDD转换为DataFrame、load和save操作、SaveMode、内置函数

    前面我们学习了Spark中的Spark core,离线数据计算,下面我们来学习一下Spark中的Spark SQL. 一.Spark SQL Spark SQL和我们之前讲Hive的时候说的hive ...

  6. python 数据库支持sql_Python 对数据库进行SQL操作

    实现方法 1.导入依赖库 主要是导入pymysql库,用于import pymysql 2.连接数据库 建立数据库连接,准备数据连接光标. sql_1 = "insert user valu ...

  7. pandas使用to_sql方法将dataframe注册为数据库表进行数据整合和数据清洗并不对比SQL操作和dataframe操作

    pandas使用to_sql方法将dataframe注册为数据库表进行数据整合和数据清洗并不对比SQL操作和dataframe操作 SQLite 是一个软件库,实现了自给自足的.无服务器的.零配置的. ...

  8. sql 解析字符串添加到临时表中 sql存储过程in 参数输入

    sql 解析字符串添加到临时表中  sql存储过程in 参数输入 解决方法 把字符串解析 添加到 临时表中 SELECT * into #临时表   FROM dbo.Func_SplitOneCol ...

  9. 14、ORACLE下的基本SQL操作

    ORACLE下的基本SQL操作 1.获取表字段 select * from user_tab_columns where Table_Name='用户表' order by column_name 2 ...

最新文章

  1. Python实现1-9数组形成的结果为100的所有运算式
  2. 认识 Linux 系统结构
  3. 音视频技术开发周刊 | 201
  4. Equipment download - individual object以及object structure创建细节
  5. iOS之github第三方框架(持续更新)
  6. Eureka缓存机制
  7. element 时间选择器——年
  8. Netty工作笔记0009---Channel基本介绍
  9. java栈顶元素_栈(Stack)
  10. webgl与opengl技术资讯
  11. angular 表单操作
  12. android 放大镜功能,Android 做一个放大镜的效果(转)
  13. 美国杜克大学计算机专业世界排名,美国杜克大学世界排名是多少呢?
  14. 关于中国教育的一些思考
  15. NewTek LightWave 3D 2018 破解版
  16. Java 抛出异常【throw】
  17. 佳驰电子冲刺科创板:年利润3.2亿 源峰磐钰与国家产投是股东
  18. 2021 年互联网大厂职级对应薪资一览表
  19. jeb 内存溢出解决方案
  20. 仿新浪微博 android,android 仿新浪微博

热门文章

  1. mac室内设计软件_MyFourwalls(家居设计软件) V1.0.10 Mac版
  2. Windows2003性能的优化方法
  3. 北京大学开设电子游戏选修课,“爆”到没地方坐
  4. 红星Linux操作系统的大部分代码处于被管控的状态
  5. win10忘记登录账户密码怎么办
  6. AD9361常见问题
  7. 后台启动appium服务
  8. 天龙服务器端修改,天龙一键端怎么架云服务器
  9. 机器人与软件工程前沿国际会议(FRSE 2023)
  10. Tired树(字典树)理解与例题