mssql 游标和循环效率比较_一文总结mssql数据库merge into语法实现及存储过程实现方式

概述

多表关联查询的时候会用到临时表插入数据,然后再用select查行查询,在往临时表里插入数据的时候,我们经常会用到判断如果临时表里有了这部分数据我们就要更新数据,如果临时表里没有这部分数据我们就要插入,这个时候可以怎么去实现呢?

下面介绍各类型数据库实现的大致方式,这里大致提了八种实现方案,因内容比较多,所以就分4部分做介绍了~


一、存储过程实现

各类型数据库都可以通过存储过程实现,因为是共性问题,所以就放前面了,这里以mysql数据库的存储过程为例。

1、环境准备

--建表create  table t1(id  bigint(10),name varchar(16),sale bigint(10),operatime datetime);create table t2(id  bigint(10),name varchar(16),sale bigint(20));-- 插入数据INSERT into t1 values(1,"xiaohong",1000,now());INSERT into t1 values(2,"xiaoming",500,now());INSERT into t2 values(1,"xiaohong",300);INSERT into t2 values(2,"xiaoming",400);INSERT into t2 values(3,"xiaoxiao",900);
6bde29e7642d0120105789997241fea1.png

2、存储过程实现

delimiter $CREATE PROCEDURE merge_t2_to_t1 () BEGIN-- 定义需要插入从a表插入b表的过程变量DECLARE _ID bigint(10);DECLARE _NAME VARCHAR (16);DECLARE _SALE VARCHAR (16);-- 游标遍历数据结束标志 DECLARE done INT DEFAULT FALSE;-- 游标指向a表结果集第一条-1位置DECLARE cur_account CURSOR FOR SELECT ID, NAME,SALE FROM t2;-- 游标指向a表结果集最后一条加1位置 设置结束标志DECLARE CONTINUE HANDLER FOR NOT FOUND  SET done = TRUE;-- 打开游标OPEN cur_account;-- 遍历游标read_loop :LOOP--  取值a表当前位置数据到临时变量    FETCH NEXT FROM cur_account INTO _ID,_NAME,_SALE; -- 如果取值结束 跳出循环IF done THEN LEAVE read_loop; END IF; -- 当前数据做对比,如果b表存在则更新时间 不存在则插入IF NOT EXISTS ( SELECT 1 FROM t1 WHERE ID = _ID AND NAME=_NAME )     THEN        INSERT INTO t1 (ID, NAME,sale,operatime) VALUES (_ID,_NAME,_sale,now());    ELSE     UPDATE t1  set sale = _sale WHERE ID = _ID AND NAME=_NAME;END IF; END LOOP;CLOSE cur_account; END $
57a84dd3a65fa19b4ce7cf4c9b8e0c62.png

3、调用存储过程

 call merge_t2_to_t1();
35c6fd414950a91d059e243be4a2e401.png

可以看到已实现了。


二、sqlserver的merge into语法

在SQL Server 2008的时候微软增加了一个强大的语句Merge。

1、语法

MERGE 语句是首先对源表和目标表都进行完全表扫描,然后拿源表和目标表检查,匹配条件,若成立则执行SQL语句1,不成立则执行SQL语句2,最执行SQL语句3。

语法:

MERGE     [ TOP ( expression ) [ PERCENT ] ]     [ INTO ]  --即将做插入、更新、删除的表    USING  --用户提供匹配条件来源的集合或者表    ON  --可以是任意有效的条件组合    [ WHEN MATCHED [ AND  ]--匹配条件成立        THEN  ]    [ WHEN NOT MATCHED [ BY TARGET ] [ AND  ]--匹配条件不成立        THEN  ]    [ WHEN NOT MATCHED BY SOURCE [ AND  ]--目标变不存在而源表存在的数据        THEN  ] ;--不要忘记分号

注意:

1)Merge操作的只是“操作表”,源表不会有任何变化

2)Merge的最后结尾必须是以分号结束的,不能忘了分号

3)语法严格要求关键字之间只能有一个英文空格,不能有多余的空格

4)不一定要把三个操作都写全,可以根据实际情况

2、实验

1)环境准备

--建表create  table t1(id   int,name VARCHAR(16),sale int,Operatime date);create  table t2(id   int,name VARCHAR(16),sale int);-- 插入数据INSERT into t1 values(1,'xiaohong',1000,sysdate);INSERT into t1 values(2,'xiaoming',500,sysdate);INSERT into t2 values(1,'xiaohong',300);INSERT into t2 values(2,'xiaoming',400);INSERT into t2 values(3,'xiaoxiao',900);commit;
701173e03e96162575adf6547d808214.png

2)merge into实现

MERGE INTO t1  USING  t2ON t1.id-t2.idWHEN MATCHED Then update set t1.sale=t2.saleWhen Not Matched When Not Matched then insert values(t2.id,t2.name,t2.sale,sysdate);--Merge的最后结尾必须是以分号结束的,不能忘了分号 谨记:语法严格要求关键字之间只能有一个英文空格,不能有多余的空格
043bda947b80e086e682c14fa95262b5.png

以上介绍了传统存储过程的实现方式和sqlserver的merge into实现方式,后面再介绍其他数据库的实现方式,感兴趣的朋友可以关注下~

7c2077b809a8ad11bdc103e0abc63806.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值