因为工作中常用到 合并两张表中的数据,主要是写下来给自己备忘,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. pcDuino安装vnc进行远程控制

    准备工作: 已经刷好的 pcduino : 点此购买   可选用显示器或者用ssh连接,ssh连接参考 无显示器刷机与使用 1.安装x11vnc 输入下面的命令: sudo apt-get insta ...

  2. WebTable 扩展

    # coding:utf-8 """ 页面 table处理 """ from selenium import webdriver from ...

  3. Xcode插件筛选

    Xcode高效插件推荐 好像很多iOS开发的同学都不知道Xcode有插件这么一说,所以整理了一下自己用的Xcode高效插件,分享给大家 下列插件在Xcode 7.0.1 版本做测试通过可以使用 在Xc ...

  4. sql日志框架log4jdbc的AOP式使用

    log4jdbc.log4j2 参考:1.  http://badqiu.iteye.com/blog/743100 2.  https://code.google.com/p/log4jdbc/ 3 ...

  5. python爬虫学习(3)_模拟登陆

    1.登陆超星慕课,chrome抓包,模拟header,提取表单隐藏元素构成params. 主要是验证码图片地址,在js中发现由js->new Date().getTime()时间戳动态生成url ...

  6. SparkContext的初始化过程分析(源码)

     SparkContext的构造函数中,最重要的入参是SparkConf  根据初始化入参生成SparkConf 再根据SparkConf来创建SparkEnv TaskScheduler.start ...

  7. 【Caffe 测试】Training LeNet on MNIST with Caffe

    Training LeNet on MNIST with Caffe We will assume that you have Caffe successfully compiled. If not, ...

  8. python的import与from...import的不同之处

    在python用import或者from...import来导入相应的模块.模块其实就是一些函数和类的集合文件,它能实现一些相应的功能,当我们需要使用这些功能的时候,直接把相应的模块导入到我们的程序中 ...

  9. java 学习笔记4

    (1)      线程的强制运行 先看线程强制运行的实例 ,再解释程序中是如何让程序强制运行的 public class ThreadTest1 implementsRunnable { public ...

  10. mvn创建web项目

    1. 新建maven项目,选择maven骨架maven-archetype-webapp来建立web项目 2. 选择next,输入groupid:MavenWebTest, artifactid:cn ...