Merge OUTPUT 高级用法综合写的一个MergeTab的存储过程

因为工作中常用到 合并两张表中的数据, 主要是写下来给自己备忘,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

  




 

转载于:https://www.cnblogs.com/Frank99/p/5400002.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值