Merge into用法总结
简单的说就是,判断表中有没有符合on()条件中的数据,有了就更新数据,没有就插入数据。
有一个表T,有两个字段a、b,我们想在表T中做Insert/Update,如果条件满足,则更新T中b的值,否则在T中插入一条记录。在Microsoft的SQL语法中,很简单的一句判断就可以了,SQL Server中的语法如下:
- if exists(select 1 from T where T.a='1001' )
- update T set T.b=2 Where T.a='1001'
- else
- insert into T(a,b) values('1001',2);
但是很明显这个语法对于SQL只能更改一条语句,并且Oracle不能使用.所以就有了Merge into(Oracle 9i引入的功能)语法
- merge into 目标表 a
- using 源表 b
- on(a.条件字段1=b.条件字段1 and a.条件字段2=b.条件字段2 ……)
- when matched then update set a.更新字段=b.字段
- when not matched then insert into a(字段1,字段2……)values(值1,值2……)
"在一个同时存在Insert和Update语法的Merge语句中,总共Insert/Update的记录数,就是Using语句中"源表"的记录数"。
源表b可能是一张表结构不同于a的表,有可能是一张构建相同表结构的临时表,也有可能是我们自己组起来的数据.
对于前两种很好理解。现在主要说一下组件数据。
对于Oracle有dual这个系统表很好构建,如下
- MERGE INTO T T1
- USING (SELECT '1001' AS a, 2 AS b FROM dual) T2
- ON ( T1.a=T2.a)
- WHEN MATCHED THEN
- UPDATE SET T1.b= T2.b
- WHEN NOT MATCHED THEN
- INSERT (a,b) VALUES(T2.a,T2.b);
在sql server中,不能使用dual这个系统变量来创建表,所以只能换下思路用union all组装数据或使用临时表,另外using中可以使用的还有table表,view视图,sub_query,子查询
- USING (
- SELECT '1001'C1,2 C2
- union all
- SELECT '1002'C1,3 C2
- union all...
- ) T2
工作中的一个实例
- public Message Saves(List<GoodsQuestionManageModel> models)
- {
- Message msg;
- StringBuilder sbSourceSql = new StringBuilder();
- if (models.Count > 0)//循环组织sql语句
- {
- int i = 1;
- foreach (GoodsQuestionManageModel model in models)
- {
- sbSourceSql.AppendFormat("select {0} GoodsQuestionManageId,{1} GoodsId,'{2}' OrderNumber,'{3}' Sku,{4} GoodsQuantity,{5} QuestionQuantity,{6} GoodsQuestionTypeId,'{7}' Remarks,{8} CreateUserId,'{9}' CreateTime,{10} LastUpdateUserId,'{11}' LastUpdateTime,{12} IsDelete \r\n",
- model.GoodsQuestionManageId, model.GoodsId, model.OrderNumber, model.Sku, model.GoodsQuantity, model.QuestionQuantity, model.GoodsQuestionTypeId, model.Remarks, GlobalModel.Instance.UserId, DateTime.Now, GlobalModel.Instance.UserId, DateTime.Now, model.IsDelete);
- if (models.Count > i++)
- {
- sbSourceSql.AppendLine(" union all");
- }
- }
- string strSql = string.Format(@"merge into tb_e_GoodsQuestionManage t
- using
- (
- {0}
- )tSource
- on (t.GoodsQuestionManageId=tSource.GoodsQuestionManageId)
- when not matched then
- insert values
- (
- tSource.GoodsId, tSource.OrderNumber, tSource.Sku, tSource.GoodsQuantity, tSource.QuestionQuantity, tSource.GoodsQuestionTypeId, tSource.Remarks, tSource.CreateUserId, tSource.CreateTime, tSource.LastUpdateUserId, tSource.LastUpdateTime, tSource.IsDelete
- )
- when matched then
- update set
- t.GoodsId=tSource.GoodsId,t.OrderNumber=tSource.OrderNumber,t.Sku=tSource.Sku,t.GoodsQuantity=tSource.GoodsQuantity,t.QuestionQuantity=tSource.QuestionQuantity,
- t.GoodsQuestionTypeId=tSource.GoodsQuestionTypeId,t.Remarks=tSource.Remarks,t.LastUpdateUserId=tSource.LastUpdateUserId,t.LastUpdateTime=tSource.LastUpdateTime,t.IsDelete=tSource.IsDelete;", sbSourceSql.ToString());
- int effectNum = SqlHelper.ExecuteNonQuery(strSql);
- if (effectNum > 0)
- {
- msg = new Message(true, "保存成功!");
- }
- else
- {
- msg = new Message(false, "保存失败!");
- }
- }
- else
- {
- msg = new Message(false, "没有数据,无需保存!");
- }
- return msg;
- }
Merge 的其他功能
Merge语句还有一个强大的功能是通过OUTPUT子句,可以将刚刚做过变动的数据进行输出。我们在上面的Merge语句后加入OUTPUT子句
此时Merge操作完成后,将所变动的语句进行输出
当然了,上面的Merge关键字后面使用了多个WHEN…THEN语句,而这个语句是可选的.也可以仅仅新增或是仅仅删除
我们还可以使用TOP关键字限制目标表被操作的行,如图8所示。在图2的语句基础上加上了TOP关键字,我们看到只有两行被更新。
但仅仅是MATCHED这种限制条件往往不能满足实际需求,我们可以在图7那个语句的基础上加上AND附加上额外的限制条件
merge into 效率很高,强烈建议使用,尤其是在一次性提交事务中,可以先建一个临时表,更新完后,清空数据,这样update锁表的几率很小了。
Merge into用法总结的更多相关文章
- SQL2008中Merge的用法
在SQL2008中,新增了一个关键字:Merge,这个和Oracle的Merge的用法差不多,只是新增了一个delete方法而已.下面就是具体的使用说明: 首先是对merge的使用说明: merge ...
- SQL中Merge的用法
SQL中Merge的用法 Merge的用法 Merge可以完成以下功能: 1. 两个表之间数据的更新 2. 进行进销存更新库存 3. 进行表之间数据的复制 语法说明: 1. 在语句结束后一定要 ...
- SQL2008中Merge的用法(轉載)
在SQL2008中,新增了一个关键字:Merge,这个和Oracle的Merge的用法差不多,只是新增了一个delete方法而已.下面就是具体的使用说明: 首先是对merge的使用说明: merge ...
- SQL2008中Merge的用法(转)
在SQL2008中,新增了一个关键字:Merge,这个和Oracle的Merge的用法差不多,只是新增了一个delete方法而已.下面就是具体的使用说明: 首先是对merge的使用说明: merge ...
- pandas-16 pd.merge()的用法
pandas-16 pd.merge()的用法 使用过sql语言的话,一定对join,left join, right join等非常熟悉,在pandas中,merge的作用也非常类似. 如:pd.m ...
- include的用法例子,以及include+merge的用法例子
[include+LinearLayout]的使用例子 AndroidIncludeLayout.java package com.AndroidIncludeLayout; import andro ...
- oracle merge into用法
转载:http://blog.163.com/duanpeng3@126/blog/static/885437352011724104741817/ 在 平时更新数据时,经常有这样一种更新,即将目标表 ...
- Oracle 的merge into 用法
1.merge into的用途 Merge是一个非常有用的功能,与DB2中的merge into功能几乎一样,与Mysql里的insert into on duplicate key也很类似.MERG ...
- ORCAL Merge into用法总结
简单的说就是,判断表中有没有符合on()条件中的数据,有了就更新数据,没有就插入数据. 有一个表T,有两个字段a.b,我们想在表T中做Insert/Update,如果条件满足,则更新T中b的值,否则在 ...
- git rebase和git merge的用法
http://softlab.sdut.edu.cn/blog/subaochen/2016/01/git-rebase%E5%92%8Cgit-merge%E7%9A%84%E7%94%A8%E6% ...
随机推荐
- 鸿蒙内核源码分析(寄存器篇) | 小强乃宇宙最忙存储器 | 百篇博客分析OpenHarmony源码 | v38.02
百篇博客系列篇.本篇为: v38.xx 鸿蒙内核源码分析(寄存器篇) | 小强乃宇宙最忙存储器 | 51.c.h .o 硬件架构相关篇为: v22.xx 鸿蒙内核源码分析(汇编基础篇) | CPU在哪 ...
- YbtOJ#493-最大分数【斜率优化dp,分治】
正题 题目链接:http://www.ybtoj.com.cn/contest/117/problem/1 题目大意 \(n\)个数的一个序列,给其中的一些数打上标记. 一个标记方案的贡献为\(s_1 ...
- vulnhub靶机-Me and My Girlfriend: 1
vulnhub靶机实战 1.靶机地址:https://www.vulnhub.com/entry/me-and-my-girlfriend-1,409/ 2.先看描述(要求) 通过这个我们可以知道我们 ...
- C++默认参数静态绑定
先来看这样一段代码 class Base { public: virtual void print(int a = 1) const { std::cout << "Base & ...
- Google Style Guides
Google Style Guides Google Style Guides Google 开源项目风格指南 (zh-google-styleguide.readthedocs.io)
- ArrayList和Vector
ArrayList和Vector ArrayList ArrayList的注意实现 1.ArrayList可以加入null,并且多个 2.ArrayList是由数组来实现数据存储的 3.ArrayLi ...
- 2021-2022 20211420 《信息安全专业导论》安装Linux操作系统并学习Linux基础
作业信息 |作业属于|https://edu.cnblogs.com/campus/besti/2021-2022-1fois |作业要求|https://edu.cnblogs.com/campus ...
- 【UE4】GAMES101 图形学作业0:矩阵初识
作业描述 给定一个点P=(2,1), 将该点绕原点先逆时针旋转45◦,再平移(1,2), 计算出变换后点的坐标(要求用齐次坐标进行计算). UE4 知识点 主要矩阵 FMatrix FBasisVec ...
- Java:死锁编码及定位分析
Java:死锁编码及定位分析 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 概念 死锁是指两个或多个以上的进程在执行过程中,因争夺资源而造成一种互相等待的现象, ...
- Noip模拟33垫底反思 2021.8.8
T1 Hunter 考场上没写$%p$挂了25分.也是很牛皮,以后打完过了样例一定要检查 因为样例太小了......很容易忘记%%%% 正解随便手模就出来了. 1 #include<bits/s ...