.Net中DataAdapter批量插入和更新数据总结
前言
前段时间一直在忙着项目上线,在做项目的同时遇到了一些之前不曾碰到的问题,因为没有经验,只能从网上找一些相关的解决方案,但是网上提供的资料实在是太杂,有的根本不能用,耗时又耗力。
我希望把我这段时间遇到的问题记录下来,去帮助那些当时和我一样“饥渴”的人,以减少时间成本,大家放心,遇到的这些问题提供的解决方案都是经过我们测试,现在正在用的,基本上没什么问题。有什么问题,大家也可以进行探讨,因为问题很多,有些记不起来了,我只能写些可以记起来的分享给大家。
插一句,就是大家在搜问题的时候,尽量用关键字,不是你搜不到问题的答案,而是你搜问题的方式有问题,而且尽量用google,大家用过就知道为什么了,看不懂的有google翻译。
批量插入
我们在.net操作大数据的时候,有时候会遇到大量数据插入的情况,遇到这种方式,我们遇到最笨的方式是forearch插入,很少的数据是可以,但是几千条,几万条就死掉了,这种方式性能很差。既然如此,微软不可能没有好的解决方案的,这就是DataAdapter,我贴下批量插入的:
public static bool MultiInsertData(DataSet ds, string Columns, string tableName)
{
using (OracleConnection connection = new OracleConnection(connectionString))
{
string SQLString = string.Format("select {0} from {1} where rownum=0", Columns, tableName);
using (OracleCommand cmd = new OracleCommand(SQLString, connection))
{
try
{
connection.Open();
OracleDataAdapter myDataAdapter = new OracleDataAdapter();
myDataAdapter.SelectCommand = new OracleCommand(SQLString, connection);
myDataAdapter.UpdateBatchSize = ;
OracleCommandBuilder custCB = new OracleCommandBuilder(myDataAdapter);
DataTable dt = ds.Tables[].Copy();
DataTable dtTemp = dt.Clone(); int times = ;
for (int count = ; count < dt.Rows.Count; times++)
{
for (int i = ; i < && * times + i < dt.Rows.Count; i++, count++)
{
dtTemp.Rows.Add(dt.Rows[count].ItemArray);
}
myDataAdapter.Update(dtTemp);
dtTemp.Rows.Clear();
} dt.Dispose();
dtTemp.Dispose();
myDataAdapter.Dispose();
return true;
}
catch (System.Data.OracleClient.OracleException E)
{
connection.Close();
return false;
}
}
}
}
大家都是搞编程的,一看就明白,我就简单的说下,参数ds是要更新的数据集,Columns是要插入的列表,TableName是要插入的表名,这里需要强调的一点是,插入数据集里的表的字段和类型必须和数据库那边一致,这点重要,要不然插入会报错。
这里还有加了个分段插入,就是那个for,每400条插入一次,这样可以避免插入的数据太大,会发生超时异常。
我做项目的时候遇到这种情况是:有些数据是要先保存到本地,比如SqlLite,然后再上传到数据库。
这里给大家个建议,如果用到wcf,就在传输前对数据集进行压缩,然后到服务端再解压下,这样传输速度会很快。有时间给大家提供压缩的方法。
批量更新
批量更新和批量插入差不多的逻辑,我先贴下代码:
public static bool MultiUpdateData(DataTable data, string Columns, string tableName)
{
using (OracleConnection connection = new OracleConnection(connectionString))
{
string SQLString = string.Format("select {0} from {1} where rownum=0", Columns, tableName);
using (OracleCommand cmd = new OracleCommand(SQLString, connection))
{
try
{
connection.Open();
OracleDataAdapter myDataAdapter = new OracleDataAdapter();
myDataAdapter.SelectCommand = new OracleCommand(SQLString, connection);
OracleCommandBuilder custCB = new OracleCommandBuilder(myDataAdapter);
custCB.ConflictOption = ConflictOption.OverwriteChanges;
custCB.SetAllValues = true;
foreach (DataRow dr in data.Rows)
{
if (dr.RowState == DataRowState.Unchanged)
dr.SetModified();
}
myDataAdapter.Update(data);
data.AcceptChanges();
myDataAdapter.Dispose();
return true;
}
catch (System.Data.OracleClient.OracleException E)
{
connection.Close();
return false;
}
}
}
}
大家看代码发现和上面插入是差不多的,但是有几点注意的地方我说下,数据集行的状态RowState必须是Modified状态,不是的话需要设置一下,还有就是更新的数据集中必须包含主键,没有的话就会报错。
重要的一点就是data.AcceptChanges();这句代码,如果注释掉的话,虽然myDataAdapter.Update(data);这段代码更新了,但是数据库那边还是不行的,我的理解是这样:Adapter本身是适配器的意思,适配器是连接两个物体之间的桥梁,就像协议一样,两边都通过才可以完成整个过程。data.AcceptChanges();的意思是应用数据集的更改,我测试过在数据集传输之前应用更新,也是可以更新到数据库的,可能就是dr.SetModified();这段代码在控制吧,如果数据库中的数据在数据集中发生变化,就会生成相应的Uodate,执行更新,这些都是我的猜测,底层的东西我不是很了解,这也是我欠缺的地方,等项目上线完一定要恶补下。
批量更新我应用的场景是:datagridview绑定查询的数据,对数据进行修改,然后批量更新到数据库。
希望可以帮到需要帮助的朋友。。。
.Net中DataAdapter批量插入和更新数据总结的更多相关文章
- mybatis 注解的方式批量插入,更新数据
一,当向数据表中插入一条数据时,一般先检查该数据是否已经存在,如果存在更新,不存在则新增 使用关键字 ON DUPLICATE KEY UPDATE zk_device_id为主键 model ...
- SQL server 批量插入和更新数据
批量插入数据 insert into A表数据库名.[dbo].A(a,b,c) (select a,b,c from B表数据库名.[dbo].B) 批量更新数据 根据身份证第二位更新性别 upda ...
- Mybatis 向oracle批量插入与更新数据
插入 <insert id="batchSave" parameterType="java.util.List"> INSERT INTO T_UP ...
- C#使用SqlDataAdapter 实现数据的批量插入和更新
近日由于项目要求在需要实现中型数据的批量插入和更新,晚上无聊,在网上看到看到这样的一个实现方法,特摘抄过来,以便以后可能用到参考. 一.数据的插入 DateTime begin = DateTime. ...
- Python中elasticsearch插入和更新数据的实现方法
Python中elasticsearch插入和更新数据的实现方法 这篇文章主要介绍了Python中elasticsearch插入和更新数据的实现方法,需要的朋友可以参考下 首先,我的索引结构是酱紫的. ...
- MySQL on duplicate key update 批量插入并更新已存在数据
业务上经常存在一种现象,需要批量往表中插入多条数据,但在执行过程中,很可能因为唯一键冲突,而导致批量插入失败.因此需要事先判断哪些数据是重复的,哪些是新增的.比较常用的处理方法就是找出已存在的数据,并 ...
- SQL语句-批量插入表(表数据插表)
批量插入表(表数据插表) ****1.INSERT INTO SELECT语句语句形式为:Insert into Table2(field1,field2,...) select value1,val ...
- java批量插入或更新的问题
在批量插入或者更新中,setXXX的时候字段类型必须一致.例如:在普通sql中 pstmt8.setBigDecimal(j ,xxx);可以写成pstmt8.setString(j,xxx.toSt ...
- Cassandra1.2文档学习(10)—— 插入和更新数据
参考数据:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/dml/dml_about_ ...
随机推荐
- cf 红名计划!
我要成为红名爷! 这是现在好弱好弱的窝 >_< ****************UPD ON 2015/12/10 0:20 啊啊啊啊啊啊啊啊啊啊啊啊把时间记错了啊QAQ 我也不知道为什么 ...
- Servlet解决参数乱码问题
为什么会产生乱码? 之所以会产生乱码,是由于服务器端和客户端的编码方式不一致造成的.客户端与服务器端的交互过程中,存在着两次数据交换:第一次,客户端向服务器端发起请求,第二次数据交换,服务器端响应客户 ...
- 使用Python中PIL图形库进行截屏
目的:通过使用Python的一个图形库PIL(Python Image Library)对屏幕进行截图 步骤: 1.下载PIL(路径)并安装 2.新建文件“截屏.py”,右键Edit with IDL ...
- wdk中ramdisk代码解读
入口函数,即驱动加载函数 NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) ...
- java中类的加载情况
当一个类存在继承且与其他类有关联情况时,类中各模块加载顺序如下: 1.首先找到public类,判断该类是否继承其他类,如果没有继承其他类(Object类除外),则加载该类:否则转去加载该类的超类,超类 ...
- Android图片资源
title: 2016-5-5未命名文件 tags: UI适配,图片资源 grammar_cjkRuby: true --- 概述: 本文整理了Android开发中,图片资源的提供方式和使用方式.包括 ...
- ABP理论学习之OWIN集成
返回总目录 如果你的应用中使用了OWIN,那么需要在主项目(一般来说是指Web项目)中添加Abp.Owin的nuget包,然后像下面那样在OWIN的 Startup文件中调用 UseAbp()扩展方法 ...
- 高灵活度,高适用性,高性能,轻量级的 ORM 实现
ORM(Object-Relational Mapping 对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,目的是提供易于理解的模型化数据的方法. ORM虽然有诸多好处,但是在实 ...
- 測試大型資料表的 Horizontal Partitioning 水平切割
FileGroup 檔案群組 :一個「資料庫(database)」可對應一或多個 FileGroup,一個 FileGroup 可由一或多個 file (.ndf) 構成. FileGroup 可讓 ...
- C语言 · 最小公倍数
问题描述 编写一函数lcm,求两个正整数的最小公倍数. 样例输入 一个满足题目要求的输入范例.例:3 5 样例输出 与上面的样例输入对应的输出.例: 数据规模和约定 输入数据中每一个数的范围. 例:两 ...