因为工作中常用到 合并两张表中的数据,主要是写下来给自己备忘,T-SQL 中 MERGE 的用法
WHEN MATCHED THEN UPDATE -- 中加了 后面要更新的列是否都相等,如果相等就没必要进行更新,只会 增加无用功
WHEN NOT MATCHED BY SOURCE THEN DELETE
OUTPUT $ACTION , INSERTED,DELETED, INTO... 
总而言之,就是把两张表的 MERGE 写成了一个存储过程,只需要传入相应的表名,列名,以及是否 对目的表进行相应删除的标志位
功能上算是较为灵活,但是肯定有很多没考虑到的地方,咋一看来,代码太不简洁需要重构,等有时间弄吧。本也是为了自己备忘,
如果对大家有用也很好,欢迎有兴趣的拍砖,共同完善~
下面的的存储过程能够 when matched UPDATE , 
when not matched Insert , 
WHEN NOT MATCHED THEN DELETE  
-- 使用 DeleteTargetTabFlag 这个标志位进行选择是否有必要
--从目的表中删除存在于源表而不存在于目的表中的记录,若不传这个值,那么默认是不做删除操作的
USE mydatabase
GO
IF OBJECT_ID('dbo.usp_MergeTabs') IS NOT NULL
DROP PROC dbo.usp_MergeTabs
GO
CREATE PROC dbo.usp_MergeTabs
@TarTabName varchar(128), --- 目的表名
@TarJoinCol1 varchar(20), ---目的表中用来联结的 col
@TarCol2 varchar(20), ---目的表中的要被更新或插入的列 Col2
@TarCol3 varchar(20),---目的表中的要被更新或插入的列 Col3
@SrcTabName varchar(128), --下同
@SrcJoinCol1 varchar(20),
@SrcCol2 varchar(20),
@SrcCol3 varchar(20),
@DeleteTargetFlag bit=0 ---是否从 目的表中删除标志位
AS
IF (NULLIF(@TarTabName,'')+NULLIF(@SrcTabName,'')+NULLIF(@TarJoinCol1,'')+NULLIF(@SrcJoinCol1,'')) IS NULL
BEGIN
RAISERROR('SourceTab,SrcJoinCondition or TargetTab,TarJoinCondition should not be blank',-1,-1)
RETURN;
END
ELSE
Declare @SQLCMD varchar(max) =
'MERGE INTO '+@TarTabName+' AS t
USING '+@SrcTabName+' AS r
ON r.'+@SrcJoinCol1+' = t.'+@TarJoinCol1+'
WHEN MATCHED',
@UpdateSQL varchar(max)='',
@InsertSQL varchar(max)='',
@ValueSQL varchar(max)='',
@UpdateCon varchar(max)='',
@OutputSQL varchar(max)='OUTPUT '+char(10),
@IntoTab varchar(max)='IF OBJECT_ID(''shopping.dbo.OutputTemp'',''U'') IS NOT NULL'+CHAR(13)+'DROP TABLE dbo.OutputTemp'+char(10)+''+char(13)--+' DROP TABLE dbo.OutputTemp'
SET @UpdateSQL=CASE WHEN NULLIF(@TarCol2,'')+NULLIF(@SrcCol2,'') IS NULL
THEN
CASE WHEN NULLIF(@TarCol3,'')+NULLIF(@SrcCol3,'') IS NULL THEN 'Incorrect Parameters'
ELSE 't.'+@TarCol3+' = r.'+@SrcCol3 END
WHEN NULLIF(@TarCol2,'')+NULLIF(@SrcCol2,'') IS NOT NULL THEN
CASE WHEN NULLIF(@TarCol3,'')+NULLIF(@SrcCol3,'') IS NOT NULL THEN
't.'+@TarCol2+' = r.'+@SrcCol2+','+CHAR(13)+'t.'+@TarCol3+' = r.'+@SrcCol3 --char(10)
ELSE 't.'+@TarCol2+' = r.'+@SrcCol2 END
END IF @UpdateSQL!='Incorrect Parameters'
BEGIN
SET @InsertSQL=@TarJoinCol1+','+CASE WHEN NULLIF(@TarCol2,'')+NULLIF(@SrcCol2,'') IS NULL THEN @TarCol3
WHEN NULLIF(@TarCol3,'')+NULLIF(@SrcCol3,'') IS NULL THEN @TarCol2
ELSE @TarCol2+','+@TarCol3
END SET @ValueSQL=@SrcJoinCol1+','+CASE @InsertSQL WHEN @TarJoinCol1+','+@TarCol3 THEN 'r.'+@SrcCol3
WHEN @TarJoinCol1+','+@TarCol2 THEN 'r.'+@SrcCol2
ELSE 'r.'+@SrcCol2+','+'r.'+@SrcCol3
END SET @OutputSQL+=CASE @InsertSQL WHEN @TarJoinCol1+','+@TarCol3 THEN 'inserted.'+@TarJoinCol1+','+'inserted.'+@SrcCol3+' AS New'+@SrcCol3+CHAR(10)+',deleted.'+@SrcCol3++' AS Old'+@SrcCol3
WHEN @TarJoinCol1+','+@TarCol2 THEN 'inserted.'+@TarJoinCol1+','+'inserted.'+@SrcCol2++' AS New'+@SrcCol2+CHAR(13)+',deleted.'+@SrcCol2+' AS Old'+@SrcCol2
ELSE 'inserted.'+@TarJoinCol1+','+'inserted.'+@SrcCol2++' AS New'+@SrcCol2+CHAR(13)+',deleted.'+@SrcCol2+' AS Old'+@SrcCol2+char(10)+',inserted.'+@SrcCol3+' AS New'+@SrcCol3+CHAR(10)+',deleted.'+@SrcCol3++' AS Old'+@SrcCol3
END +',$action AS Action INTO dbo.OutputTemp'
SET @UpdateCon+=' AND '+CASE @InsertSQL WHEN @TarJoinCol1+','+@TarCol3 THEN 'r.'+@SrcCol3+' <> t.'+@TarCol3
WHEN @TarJoinCol1+','+@TarCol2 THEN 'r.'+@SrcCol2+' <> t.'+@TarCol2
ELSE 'r.'+@SrcCol2+' <> t.'+@TarCol2+' OR '+'r.'+@SrcCol3+' <> t.'+@TarCol3
END
SET @IntoTab +='SELECT '+REPLACE(REPLACE(REPLACE(REPLACE(@OutputSQL,'inserted','r'),'deleted','r'),',$action AS Action INTO dbo.OutputTemp',''),'OUTPUT','')+CHAR(10)
+'INTO dbo.OutputTemp FROM '+@TarTabName+' AS r'+CHAR(10)+CHAR(13)
+'ALTER TABLE dbo.OutputTemp ADD [Action] varchar(20)'+CHAR(10)+' '
EXEC (@IntoTab)
print @IntoTab
SET @SQLCMD+=@UpdateCon+' THEN
UPDATE SET
'
IF @DeleteTargetFlag!=0
BEGIN
SET @SQLCMD+=@UpdateSQL+'
WHEN NOT MATCHED THEN
INSERT('+@InsertSQL+')'+'
VALUES('+@ValueSQL+')
WHEN NOT MATCHED BY SOURCE THEN
DELETE;'
END
ELSE
SET @SQLCMD+=@UpdateSQL+'
WHEN NOT MATCHED THEN
INSERT('+@InsertSQL+')'+'
VALUES('+@ValueSQL+')'+CHAR(10)+@OutputSQL+'
;'
print (@SQLCMD)
exec (@SQLCMD)
END
ELSE
RAISERROR(@UpdateSQL,-1,-1);
RETURN; --------------测试数据-------------- IF OBJECT_ID('dbo.TarTab','U') IS NOT NULL
DROP TABLE dbo.TarTab
GO CREATE TABLE dbo.TarTab(StuID int,StuName varchar(15),StuGender char(6))
GO INSERT INTO dbo.TarTab
VALUES(1,'Marry','Female'),
(2,'Tom','Female'),
(3,'Frank','male'),
(4,'Jim','Female'),
(5,'Tom','Female'),
(6,'Sera','Male')
GO IF OBJECT_ID('dbo.SrcTab','U') IS NOT NULL
DROP TABLE dbo.SrcTab
GO CREATE TABLE dbo.SrcTab(StuID int,StuName varchar(15),StuGender char(6))
GO
INSERT INTO dbo.SrcTab
VALUES(1,'Marry','Female'),
(2,'Tom','Female'),
(3,'Frank','male'),
--(4,'Jim','Male'),
--(5,'Tom','Male'),
(6,'Sera','Female'),
(7,'Mongo','FeMale'),
(100,'KangKang','Male')
--SELECT * FROM dbo.TarTab
--select * from dbo.SrcTab
--StuID int,StuName varchar(15),StuGender
exec dbo.usp_MergeTabs
@TarTabName='dbo.TarTab'
,@TarJoinCol1='StuID'
,@TarCol2='StuName'
,@TarCol3='StuGender'
,@SrcTabName='dbo.SrcTab'
,@SrcJoinCol1='StuID'
,@SrcCol2=''
,@SrcCol3='StuGender'
,@DeleteTargetFlag=1 --0 --drop table outputtemp
select * from dbo.OutputTemp select * from dbo.SrcTab

  

Merge OUTPUT 高级用法综合写的一个MergeTab的存储过程的更多相关文章

  1. Python3高级用法综合举例

    [本文出自天外归云的博客园] 举例 下面代码围绕一个Student类综合举例说明装饰器.生成器.动态获取/添加类成员.列表推导式.reduce函数.lambda表达式的实际应用: from funct ...

  2. 写了一个常规性生成merge 的小脚本

    现在使用数据库来写存储过程,动不动参数就会用到xml ,当然罗,优势也很明显,参数相对固定,而且灵活,如果要修改或者什么的,中间接口层也不需要做变化,只需要修改封装的存储过程以及程序传参就ok了. 随 ...

  3. break 的一个“高级用法”(转)

    转载:http://blog.csdn.net/lovelan1748/article/details/5321558 本小节不是很适于没有多少实际编程经历的初学者,所以初学者可以跳过,以后再回头阅读 ...

  4. 多年经验,教你写出最惊艳的 Markdown 高级用法

    点赞再看,养成习惯,微信搜索[高级前端进阶]关注我. 本文 GitHub https://github.com/yygmind 已收录,有一线大厂面试完整考点和系列文章,欢迎 Star. 最近在学习的 ...

  5. 多年经验总结,写出最惊艳的 Markdown 高级用法

    点赞再看,养成习惯,微信搜索[高级前端进阶]关注我. 本文 GitHub https://github.com/yygmind 已收录,有一线大厂面试完整考点和系列文章,欢迎 Star. 最近在学习的 ...

  6. nmap命令-----高级用法

    探测主机存活常用方式 (1)-sP :进行ping扫描 打印出对ping扫描做出响应的主机,不做进一步测试(如端口扫描或者操作系统探测):  下面去扫描10.0.3.0/24这个网段的的主机 nmap ...

  7. arr的高级用法

    arr的高级用法 reduce 方法(升序) 语法: array1.reduce(callbackfn[, initialValue]) 参数 定义 array1 必需.一个数组对象. callbac ...

  8. Git log高级用法

    格式化Log输出 首先,这篇文章会展示几种git log格式化输出的例子.大多数例子只是通过标记向git log请求或多或少的信息. 如果你不喜欢默认的git log格式,你可以用git config ...

  9. Python3基础-高级用法

    写在前面:本文主要是python高级练习部分,介绍了一些高级用法,这些都是零散的小知识,这些可以与函数式编程合在一起使用. 函数式编程1:Python中提供的函数式编程主要有: map(函数,可迭代式 ...

随机推荐

  1. C# 防止同一个账号多次登录(cache方法)

    c#中防止同一账号重复登录的方法有不少,比如用数据库来记录用户登录情况.用Application来保存用户登录信息.用Cache来保存信息等. 本文为大家介绍如何利用缓存Cache方便地实现此功能. ...

  2. [C# 网络编程系列]专题四:自定义Web浏览器

    转自:http://www.cnblogs.com/zhili/archive/2012/08/24/WebBrowser.html 前言: 前一个专题介绍了自定义的Web服务器,然而向Web服务器发 ...

  3. format 对整形的应用

    对于整型数,会在整型值的前面以0补之 Format('this is %.7d'[1234]);             输出是:this is 0001234]

  4. HW4.18

    public class Solution { public static void main(String[] args) { System.out.println("Graph 1&qu ...

  5. Dynamic Library Design Guidelines

    https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100 ...

  6. Nginx具体的压缩配置

    以下是自学it网--中级班上课笔记 网址:www.zixue.it 常用以下配置 gzip on|off gzip_buffers 4K|8K 缓冲(和硬盘块相当) gzip_comp_level [ ...

  7. Robot Framework自动化测试环境准备(一)

    Robot framework是诺西(NSN)开源的一套自动化测试工具,在通信设备自动化测试中很实用,它基于Python开发,主要模拟NMS网管配置数据到网元NODE,并读取配置看配置是否生效. == ...

  8. Git 版本控制工具(学习笔记)

    GIT(分布式) 一.Git 初始版本控制工具 1. 安装Git Ubuntu系统下,打开shell界面,输入: sudo apt-get install git-core  之后回车输入密码,即可完 ...

  9. 第一个小项目(天气预报软件)——称"酷狗天气"

    一.创建数据库和表 分析: 二.遍历全国省市县数据 分析: 三.显示天气信息 分析: 四.切换城市和手动更新天气 分析: 五.后台自动更新天气 分析:

  10. Android源代码之Gallery专题研究(1)

    前言 时光飞逝,从事Android系统开发已经两年了,总想写点什么来安慰自己.思考了非常久总是无法下笔,认为没什么好写的.如今最终决定写一些符合大多数人需求的东西,想必使用过Android手机的人们一 ...