点击查看代码
USE []
GO
/****** Object: StoredProcedure [dbo].[Proc_Comapre_Table_Content] Script Date: 2022/7/25 18:59:36 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Proc_Comapre_Table_Content]
@TableName1 nvarchar(64),
@TableName2 nvarchar(64),
@ExceptCol nvarchar(256) = '',
@DbName1 nvarchar(64) = '',
@DbName2 nvarchar(64) = '',
@CompareCount int = 30000
AS
--------------------------------
-- 1.check
--------------------------------
-- ErrorCode : 10001 Message: 表不存在
-- ErrorCode : 10002 Message: 表结构不一致
Declare @CheckSql nvarchar(max)
Declare @CompareId nvarchar(64) -- 比较ID
Select @CompareId = newId()
Declare @CompareTime datetime = getdate() -- 比较时间
Declare @CompareResult nvarchar(1) -- 比较结果
Declare @CompareErrorCode nvarchar(10) -- 错误Code
Declare @CompareErrorMessage nvarchar(10) -- 错误信息
-- 获取需要比较的列
DeClare @CompareCol1 nvarchar(max)
DeClare @CompareCol2 nvarchar(max)
Select @CompareCol1 = STUFF((select ',' + COLUMN_name from INFORMATION_SCHEMA.columns where TABLE_NAME = @TableName1
and COLUMN_NAME not in (''''+ @ExceptCol +'''')
FOR XML PATH('')), 1, 1, '')
Select @CompareCol2 = STUFF((select ',' + COLUMN_name from INFORMATION_SCHEMA.columns where TABLE_NAME = @TableName2
and COLUMN_NAME not in (''''+ @ExceptCol +'''')
FOR XML PATH('')), 1, 1, '')
-- 表结构比对
IF @CompareCol1 <> @CompareCol2
BEGIN
Set @CompareResult = '2'
Set @CompareErrorCode = 'ErrCd10001'
Set @CompareErrorMessage = 'Table structure is not same .'
Goto SaveErrorResult
END
--------------------------------
-- 2.compare
--------------------------------
Declare @CompareSql nvarchar(max)
Declare @CompareCountSql nvarchar(max)
Declare @DifferentCount int
Set @CompareSql = 'Select ' + @CompareCol1 + ' from ' + @TableName1 + ' except ' + ' Select ' + @CompareCol2 + ' from ' + @TableName2
Set @CompareCountSql = N'Select @DifferentCount = Count(*) from (' + @CompareSql + N')t'
Exec sys.sp_executesql @CompareCountSql, N'@DifferentCount int OUTPUT' , @DifferentCount OUTPUT ;
-- 判断比对结果
IF @DifferentCount = 0
BEGIN
Set @CompareResult = '0'
Set @CompareErrorCode = ''
Set @CompareErrorMessage = ''
GOTO SaveSuccessedResult1
END
ELSE
BEGIN
Set @CompareResult = '1'
Set @CompareErrorCode = ''
Set @CompareErrorMessage = ''
GOTO SaveSuccessedResult2
END
-- EXEC (@CompareSql)
--------------------------------
-- 3.Save Result
--------------------------------
SaveErrorResult:
Insert Into CompareLogHeader values(@CompareId,@CompareTime,@CompareResult,@CompareErrorCode,@CompareErrorMessage,@TableName1
,@TableName2,@ExceptCol,@DbName1,@DbName2,@CompareCount,getdate())
Return
SaveSuccessedResult1:
Insert Into CompareLogHeader values(@CompareId,@CompareTime,@CompareResult,@CompareErrorCode,@CompareErrorMessage,@TableName1
,@TableName2,@ExceptCol,@DbName1,@DbName2,@CompareCount,getdate())
Return
SaveSuccessedResult2:
Insert Into CompareLogHeader values(@CompareId,@CompareTime,@CompareResult,@CompareErrorCode,@CompareErrorMessage,@TableName1
,@TableName2,@ExceptCol,@DbName1,@DbName2,@CompareCount,getdate())
DECLARE @InsertDetailSql nvarchar(max)
Set @InsertDetailSql = N'Insert Into CompareLogDetails
Select @CompareId , CompareItem , ''I'' as DifferentType , (
Select * From
(
Select ROW_NUMBER() over(order by (select 1)) as CompareItem , * From (' + @CompareSql + ')t
)d2
Where d2.CompareItem = d1.CompareItem
For Json Path
) As TableContent1
, '''' As TableContent2 , getDate() As InsertTime
From (
Select ROW_NUMBER() over(order by (select 1)) as CompareItem , * From (' + @CompareSql + ')t
)d1
'
Exec sys.sp_executesql @InsertDetailSql,N'@CompareId nvarchar(64)' ,@CompareId = @CompareId;
完整版
点击查看代码
ALTER PROCEDURE [dbo].[Proc_Comapre_Table_Content]
@TableName1 nvarchar(64),
@TableName2 nvarchar(64),
@ExceptCol nvarchar(256) = '',
@DbName1 nvarchar(64) = '',
@DbName2 nvarchar(64) = '',
@CompareCount int = 30000
AS
--------------------------------
-- 1.check 表结构对比,可能存在:1.当两表的列名不相等时,判断两表结构、数据不一样
---2.当两表列名、数量相等时,但数据可能存在差异
--------------------------------
-- ErrorCode : 10001 Message: 表不存在
-- ErrorCode : 10002 Message: 表结构不一致
Declare @CheckSql nvarchar(max)
Declare @CompareId nvarchar(64) -- 比较ID
Select @CompareId = newId()
Declare @CompareTime datetime = getdate() -- 比较时间
Declare @CompareResult nvarchar(1) -- 比较结果
Declare @CompareErrorCode nvarchar(10) -- 错误Code
Declare @CompareErrorMessage nvarchar(10) -- 错误信息
-- 获取需要比较的列
DeClare @CompareCol1 nvarchar(max)
DeClare @CompareCol2 nvarchar(max)
Select @CompareCol1 = STUFF((select ',' + COLUMN_name from INFORMATION_SCHEMA.columns where TABLE_NAME = @TableName1
and COLUMN_NAME not in (''''+ @ExceptCol +'''')
FOR XML PATH('')), 1, 1, '')
Select @CompareCol2 = STUFF((select ',' + COLUMN_name from INFORMATION_SCHEMA.columns where TABLE_NAME = @TableName2
and COLUMN_NAME not in (''''+ @ExceptCol +'''')
FOR XML PATH('')), 1, 1, '')
---获取两表的列名且不为空(' ')
-- 表结构比对
IF @CompareCol1 <> @CompareCol2
----当两表的列名不相等时,判断两表结构、数据不一样
BEGIN
Set @CompareResult = '2'
---结果赋值2代表两表数据结构不一样
Set @CompareErrorCode = 'ErrCd10001'
Set @CompareErrorMessage = 'Table structure is not same .'
----表结构不一样
Goto SaveErrorResult
----跳转到SaveErrorResult,将判断结果导入CompareLogHeader表中
END
--------------------------------
-- 2.compare 表数据对比 可能存在: 1.两表数据完全一样,不存在差异。
-----2.两表数据不一样,纯在差异。
--------------------------------
Declare @CompareSql nvarchar(max)
---两表except得出差异数据
Declare @CompareCountSql nvarchar(max)
---count差异数据列数
Declare @DifferentCount int
---差异数据列数
Set @CompareSql = 'Select ' + @CompareCol1 + ' from ' + @TableName1 + ' except ' + ' Select ' + @CompareCol2 + ' from ' + @TableName2
Set @CompareCountSql = N'Select @DifferentCount = Count(*) from (' + @CompareSql + N')t'
Exec sys.sp_executesql @CompareCountSql, N'@DifferentCount int OUTPUT' , @DifferentCount OUTPUT ;
-- 判断比对结果
IF @DifferentCount = 0
--- 当差异数据列数=0时,说明无差异数据
BEGIN
Set @CompareResult = '0'
---赋值0代表无差异数据
Set @CompareErrorCode = ''
Set @CompareErrorMessage = ''
GOTO SaveSuccessedResult1
---跳转执行SaveSuccessedResult1将判断结果导入CompareLogHeader表中
END
ELSE
BEGIN
Set @CompareResult = '1'
---赋值1代表有差异数据
Set @CompareErrorCode = ''
Set @CompareErrorMessage = ''
GOTO SaveSuccessedResult2
---跳转执行SaveSuccessedResult2将判断结果导入CompareLogHeader表中
END
-- EXEC (@CompareSql)
--------------------------------
-- 3.Save Result 比对结果,根据不同的可能结果,输出对应的表
--------------------------------
SaveErrorResult:
--两表结构、数据不一样得到下表
Insert Into CompareLogHeader values(@CompareId,@CompareTime,@CompareResult,@CompareErrorCode,@CompareErrorMessage,@TableName1
,@TableName2,@ExceptCol,@DbName1,@DbName2,@CompareCount,getdate())
Return
SaveSuccessedResult1:
--无差异数据时,得到下表
Insert Into CompareLogHeader values(@CompareId,@CompareTime,@CompareResult,@CompareErrorCode,@CompareErrorMessage,@TableName1
,@TableName2,@ExceptCol,@DbName1,@DbName2,@CompareCount,getdate())
Return
SaveSuccessedResult2:
---当有两表结构一致存在差异数据是得到下表
-- 将主键保存在临时表中
Declare @ConditionSql NVARCHAR(max)
Declare @TypeSql NVARCHAR(256)
Declare @TableContent2 NVARCHAR(256)
Declare @ICount NVARCHAR(max) = 0
Declare @Index NVARCHAR(256)
--获取@TableName1的主键放入临时表中
create Table #Temp_Indexs(indexs nvarchar(50))
Exec ('Insert Into #Temp_Indexs SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME=''' + @TableName1 + '''')
-- 声明游标
DECLARE Indexs CURSOR FAST_FORWARD FOR
SELECT *
FROM #Temp_Indexs
---游标遍历临时表获取主键名
OPEN Indexs;
-- 取第一条记录
FETCH NEXT FROM Indexs INTO @Index;
WHILE @@FETCH_STATUS=0
BEGIN
If @ICount = 0 ---当 If @ICount = 0 时 只有一条数据取 join 条件为 on a.x=b.x
BEGIN
Set @ConditionSql = ' d1.' + @Index + '= d3.' + @Index
Set @TypeSql = 'd3.' + @Index
END
Else
BEGIN Set @ConditionSql = ' AND d1.' + @Index + '= d3.' + @Index END
---当 If @ICount <> 0 时 取第一条数据取 join 条件为 on a.x=b.x 第二条是为 and a.y=b.y
-- 取下一条记录
FETCH NEXT FROM Indexs INTO @Index;
-- 操作
Set @ICount = @ICount +1 --计数,方便判断取第几条数据
END
-- 关闭游标
CLOSE Indexs;
-- 释放游标
DEALLOCATE Indexs;
---判断'I'还是'U'是根据最后 差异数据 left join TableName2 主键列名 后是否有数据来判断的
---最后的查询判断 TableName2.主键列名 为空 就是没join上 说明 TableName2里没有数据 判断为 插入 反之就是更新
Insert Into CompareLogHeader values(@CompareId,@CompareTime,@CompareResult,@CompareErrorCode,@CompareErrorMessage,@TableName1
,@TableName2,@ExceptCol,@DbName1,@DbName2,@CompareCount,getdate())
DECLARE @InsertDetailSql nvarchar(max)
Set @InsertDetailSql = N'Insert Into CompareLogDetails
Select @CompareId , CompareItem ,' + 'case when ' + @TypeSql + ' is null then ''I'' else ''U'' end as DifferentType ,
(Select * From
(
Select ROW_NUMBER() over(order by (select 1)) as CompareItem , * From (' + @CompareSql + ')t
)d2
Where d2.CompareItem = d1.CompareItem
For Json Path
) As TableContent1
,
(Select * From
(
Select ROW_NUMBER() over(order by (select 1)) as CompareItem , * From ' + @TableName2 + ' t
)d3
Where ' + @ConditionSql + '
For Json Path
)
As TableContent2 , getDate() As InsertTime
From (
Select ROW_NUMBER() over(order by (select 1)) as CompareItem , * From (' + @CompareSql + ')t
)d1
left join ' + @TableName2 + ' d3 on ' + @ConditionSql
Exec sys.sp_executesql @InsertDetailSql,N'@CompareId nvarchar(64)' ,@CompareId = @CompareId;
点击查看代码
CREATE PROCEDURE [dbo].[Proc_Comapre_Table_Content]
@TableName1 nvarchar(64),
@TableName2 nvarchar(64),
@CompareCol nvarchar(4000) = '',
@DbName1 nvarchar(64) = '',
@DbName2 nvarchar(64) = '',
@JobName nvarchar(64) = '',
@CompareCount int = 30000
AS
--------------------------------
-- 1.check
--------------------------------
-- ErrorCode : 10001 Message: 表不存在
-- ErrorCode : 10002 Message: 表结构不一致
Declare @CheckSql nvarchar(max)
Declare @CompareId nvarchar(64) -- 比较ID
Select @CompareId = newId()
Declare @CompareTime datetime = getdate() -- 比较时间
Declare @CompareResult nvarchar(1) -- 比较结果
Declare @CompareErrorCode nvarchar(10) -- 错误Code
Declare @CompareErrorMessage nvarchar(10) -- 错误信息
-- 获取需要比较的列
DeClare @CompareCol1 nvarchar(max)
DeClare @CompareCol2 nvarchar(max)
--Select @CompareCol1 = STUFF((select ',' + COLUMN_name from INFORMATION_SCHEMA.columns where TABLE_NAME = @TableName1
-- and COLUMN_NAME not in (''''+ @ExceptCol +'''')
-- FOR XML PATH('')), 1, 1, '')
--Select @CompareCol2 = STUFF((select ',' + COLUMN_name from INFORMATION_SCHEMA.columns where TABLE_NAME = @TableName2
-- and COLUMN_NAME not in (''''+ @ExceptCol +'''')
-- FOR XML PATH('')), 1, 1, '')
---- 表结构比对
--IF @CompareCol1 <> @CompareCol2
-- BEGIN
-- Set @CompareResult = '2'
-- Set @CompareErrorCode = 'ErrCd10001'
-- Set @CompareErrorMessage = 'Table structure is not same .'
-- Goto SaveErrorResult
-- END
--------------------------------
-- 2.compare
--------------------------------
Declare @CompareSql nvarchar(max)
Declare @CompareCountSql nvarchar(max)
Declare @DifferentCount int
Set @CompareSql = 'Select ' + @CompareCol + ' from ' + @TableName1 + ' except ' + ' Select ' + @CompareCol + ' from ' + @TableName2
Set @CompareCountSql = N'Select @DifferentCount = Count(*) from (' + @CompareSql + N')t'
Exec sys.sp_executesql @CompareCountSql, N'@DifferentCount int OUTPUT' , @DifferentCount OUTPUT ;
-- 判断比对结果
IF @DifferentCount = 0
BEGIN
Set @CompareResult = '0'
Set @CompareErrorCode = ''
Set @CompareErrorMessage = ''
GOTO SaveSuccessedResult1
END
ELSE
BEGIN
Set @CompareResult = '1'
Set @CompareErrorCode = ''
Set @CompareErrorMessage = ''
GOTO SaveSuccessedResult2
END
-- EXEC (@CompareSql)
--------------------------------
-- 3.Save Result
--------------------------------
SaveErrorResult:
Insert Into CompareLogHeader values(@CompareId,@CompareTime,@CompareResult,@CompareErrorCode,@CompareErrorMessage,@TableName1
,@TableName2,@CompareCol,@DbName1,@DbName2,@CompareCount,getdate())
Return
SaveSuccessedResult1:
Insert Into CompareLogHeader values(@CompareId,@CompareTime,@CompareResult,@CompareErrorCode,@CompareErrorMessage,@TableName1
,@TableName2,@CompareCol,@DbName1,@DbName2,@CompareCount,getdate())
Return
SaveSuccessedResult2:
-- 将主键保存在临时表中
Declare @ConditionSql NVARCHAR(max)
Declare @TypeSql NVARCHAR(256)
Declare @TableContent2 NVARCHAR(256)
Declare @ICount NVARCHAR(max) = 0
Declare @Index NVARCHAR(256)
create Table #Temp_Indexs(indexs nvarchar(50))
Exec ('Insert Into #Temp_Indexs SELECT?COLUMN_NAME?FROM?INFORMATION_SCHEMA.KEY_COLUMN_USAGE? ?
WHERE?TABLE_NAME=''' + @TableName2 + '''')
-- 声明游标
DECLARE Indexs CURSOR FAST_FORWARD FOR
SELECT *
FROM #Temp_Indexs
OPEN Indexs;
-- 取第一条记录
FETCH NEXT FROM Indexs INTO @Index;
WHILE @@FETCH_STATUS=0
BEGIN
If @ICount = 0
BEGIN
Set @ConditionSql = ' d1.' + @Index + '= d3.' + @Index
Set @TypeSql = 'd3.' + @Index
END
Else
BEGIN Set @ConditionSql = @ConditionSql + ' AND d1.' + @Index + '= d3.' + @Index END
-- 取下一条记录
FETCH NEXT FROM Indexs INTO @Index;
-- 操作
Set @ICount = @ICount +1
END
-- 关闭游标
CLOSE Indexs;
-- 释放游标
DEALLOCATE Indexs;
Insert Into CompareLogHeader values(@CompareId,@CompareTime,@CompareResult,@CompareErrorCode,@CompareErrorMessage,@TableName1
,@TableName2,@CompareCol,@DbName1,@DbName2,@CompareCount,getdate())
DECLARE @InsertDetailSql nvarchar(max)
Set @InsertDetailSql = N'Insert Into CompareLogDetails
Select @CompareId , CompareItem ,' + 'case when ' + @TypeSql + ' is null then ''I'' else ''U'' end as DifferentType ,
(Select * From
(
Select ROW_NUMBER() over(order by (select 1)) as CompareItem , * From (' + @CompareSql + ')t
)d2
Where d2.CompareItem = d1.CompareItem
For Json Path
) As TableContent1
,
(Select * From
(
Select ROW_NUMBER() over(order by (select 1)) as CompareItem , * From ' + @TableName2 + ' t
)d3
Where ' + @ConditionSql + '
For Json Path
)
As TableContent2 , '''' as ExcuteSql , getDate() As InsertTime
From (
Select ROW_NUMBER() over(order by (select 1)) as CompareItem , * From (' + @CompareSql + ')t
)d1
left join ' + @TableName2 + ' d3 on ' + @ConditionSql
Exec sys.sp_executesql @InsertDetailSql,N'@CompareId nvarchar(64)' ,@CompareId = @CompareId;
--------------------------------
-- 4.Update Target
--------------------------------
-- 定义Merge 动态语句
Declare @MergeSql Nvarchar(Max)
Set @MergeSql = N'MERGE INTO ' + @TableName2 + N' d1 ' + char(13)+char(10)+
N' USING (' + @CompareSql + N') d3' + char(13)+char(10)+
N' ON (' + @ConditionSql + N') ' + char(13)+char(10)+
N' WHEN MATCHED THEN ' + char(13)+char(10)
-- 定义更新\插入部分的语句
Declare @UpdateSql Nvarchar(Max)
Declare @InsertSourceSql Nvarchar(Max)
Declare @InsertTargetSql Nvarchar(Max)
Declare @Col NVARCHAR(256)
Set @ICount = 0
-- 定义临时表保存列名
create Table #Temp_Col(Col nvarchar(50))
Exec ('Insert Into #Temp_Col SELECT?value?FROM?STRING_SPLIT('''+@CompareCol + ''', '','')')
-- 声明游标
DECLARE Cols CURSOR FAST_FORWARD FOR
SELECT *
FROM #Temp_Col
OPEN Cols;
-- 取第一条记录
FETCH NEXT FROM Cols INTO @Col;
WHILE @@FETCH_STATUS=0
BEGIN
If @ICount = 0
BEGIN
Set @UpdateSql = ' d1.' + @Col + '= d3.' + @Col
-- Set @InsertSourceSql = ' d1.' + @Col
-- Set @InsertTargetSql = ' d3.' + @Col
--Set @TypeSql = 'd3.' + @Index
END
Else
BEGIN Set @UpdateSql = @UpdateSql + ' ,d1.' + @Col + '= d3.' + @Col
-- Set @InsertSourceSql = @InsertSourceSql + ' ,d1.' + @Col
-- Set @InsertTargetSql = @InsertTargetSql + ' ,d3.' + @Col
END
-- 取下一条记录
FETCH NEXT FROM Cols INTO @Col;
-- 操作
Set @ICount = @ICount +1
END
-- 关闭游标
CLOSE Cols;
-- 释放游标
DEALLOCATE Cols;
-- 将更新、插入逻辑加到Merge 逻辑中
Set @MergeSql = @MergeSql + N' UPDATE SET ' + char(13)+char(10)+
@UpdateSql + char(13)+char(10)+
N' WHEN NOT MATCHED THEN ' + char(13)+char(10)+
N'Insert VALUES ('
+ char(13)+char(10)+ @CompareCol
+ N',getdate(),getdate(),'''''
+ N' ); '
-- 更新目标表
Exec( @MergeSql)
点击查看代码
CREATE PROCEDURE [dbo].[Proc_Comapre_Table_Content]
@TableName1 nvarchar(64),
@TableName2 nvarchar(64),
@ConditionForTableName1 nvarchar(4000) = '',
@ConditionForTableName2 nvarchar(4000) = '',
@CompareCol nvarchar(MAX) ,
@PrimaryCol nvarchar(4000) = '',
@ReserveCol1 nvarchar(64) = '',
@ReserveCol2 nvarchar(64) = '',
@ReserveCol3 nvarchar(64) = '',
@ReserveCol4 nvarchar(64) = '',
-- @DbName1 nvarchar(64) = '',
-- @DbName2 nvarchar(64) = '',
@JobName nvarchar(64) = '',
@IsUpdateDestFlg nvarchar(64) = 0,
@Excutor nvarchar(64) = 'DW'
--@CompareCount int = 30000
AS
/*
参数说明:
@TableName1 源表名
@TableName2 目标表名
@ConditionForTableName1 源表条件限制,可选
如: @ConditionForTableName1 = N' AND Name = N''南京药石科技股份有限公司''',
@ConditionForTableName2 目标表条件限制,可选
@CompareCol 比对列
如:@CompareCol = N'Name,RegStatus,City',
@PrimaryCol 主键列(如为空则取表实际主键),可选
如:@PrimaryCol = N'Name',
@ReserveCol1 保留列1 ,可选
如: @ReserveCol1 = N'Name',
@ReserveCol2 保留列2,可选
@ReserveCol3 保留列3,可选
@ReserveCol4 保留列4,可选
@JobName 调用方作业名称,默认为空
@IsUpdateDestFlg 是否更新目标表,默认不更新
@Excutor 执行方,取值范围(BP:业务平台,DW:数仓)
*/
--------------------------------
-- 1.check
--------------------------------
-- ErrorCode : 10001 Message: 表不存在
-- ErrorCode : 10002 Message: 表结构不一致
Declare @CheckSql nvarchar(max)
Declare @CompareId nvarchar(64) -- 比较ID
Select @CompareId = newId()
Declare @CompareTime datetime = getdate() -- 比较时间
Declare @CompareResult nvarchar(1) -- 比较结果
Declare @CompareErrorCode nvarchar(10) -- 错误Code
Declare @CompareErrorMessage nvarchar(10) -- 错误信息
-- 获取需要比较的列
DeClare @CompareCol1 nvarchar(max)
DeClare @CompareCol2 nvarchar(max)
--Select @CompareCol1 = STUFF((select ',' + COLUMN_name from INFORMATION_SCHEMA.columns where TABLE_NAME = @TableName1
-- and COLUMN_NAME not in (''''+ @ExceptCol +'''')
-- FOR XML PATH('')), 1, 1, '')
--Select @CompareCol2 = STUFF((select ',' + COLUMN_name from INFORMATION_SCHEMA.columns where TABLE_NAME = @TableName2
-- and COLUMN_NAME not in (''''+ @ExceptCol +'''')
-- FOR XML PATH('')), 1, 1, '')
---- 表结构比对
--IF @CompareCol1 <> @CompareCol2
-- BEGIN
-- Set @CompareResult = '2'
-- Set @CompareErrorCode = 'ErrCd10001'
-- Set @CompareErrorMessage = 'Table structure is not same .'
-- Goto SaveErrorResult
-- END
--------------------------------
-- 2.compare
--------------------------------
Declare @CompareSql nvarchar(max)
Declare @CompareSql2 nvarchar(max)
Declare @CompareCountSql nvarchar(max)
Declare @DifferentCount int
Set @CompareSql = 'Select ' + @CompareCol + ' from ' + @TableName1 + char(13)+char(10)+
' Where 1=1 ' + @ConditionForTableName1 + char(13)+char(10)+
+ ' except ' + ' Select ' + @CompareCol + ' from ' + @TableName2 + char(13)+char(10)+
' Where 1=1 ' + @ConditionForTableName2
Set @CompareSql2 = 'Select ' + @CompareCol + ' from ' + @TableName2 + char(13)+char(10)+
' Where 1=1 ' + @ConditionForTableName2 + char(13)+char(10)+
+ ' except ' + ' Select ' + @CompareCol + ' from ' + @TableName1 + char(13)+char(10)+
' Where 1=1 ' + @ConditionForTableName1
Set @CompareCountSql = N'Select @DifferentCount = Count(*) from (' + @CompareSql + N')t'
Exec sys.sp_executesql @CompareCountSql, N'@DifferentCount int OUTPUT' , @DifferentCount OUTPUT ;
-- 判断比对结果
IF @DifferentCount = 0
BEGIN
Set @CompareResult = '0'
Set @CompareErrorCode = ''
Set @CompareErrorMessage = ''
GOTO SaveSuccessedResult1
END
ELSE
BEGIN
Set @CompareResult = '1'
Set @CompareErrorCode = ''
Set @CompareErrorMessage = ''
GOTO SaveSuccessedResult2
END
-- EXEC (@CompareSql)
--------------------------------
-- 3.Save Result
--------------------------------
SaveErrorResult:
Insert Into CompareLogHeader values(@CompareId,@CompareTime,@CompareResult,@CompareErrorCode,@CompareErrorMessage,@TableName1
,@TableName2,@CompareCol,@Excutor,0,getdate())
Return
SaveSuccessedResult1:
Insert Into CompareLogHeader values(@CompareId,@CompareTime,@CompareResult,@CompareErrorCode,@CompareErrorMessage,@TableName1
,@TableName2,@CompareCol,@Excutor,0,getdate())
Return
SaveSuccessedResult2:
-- 将主键保存在临时表中
Declare @ConditionSql NVARCHAR(max)
Declare @TypeSql NVARCHAR(256)
Declare @TableContent2 NVARCHAR(256)
Declare @ICount NVARCHAR(max) = 0
Declare @Index NVARCHAR(256)
create Table #Temp_Indexs(indexs nvarchar(50))
-- 如果主键参数是空的情况
If @PrimaryCol = ''
Begin
Exec ('Insert Into #Temp_Indexs SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME=''' + @TableName2 + '''')
End
Else
Begin
Exec ('Insert Into #Temp_Indexs SELECT Value FROM String_Split(''' + @PrimaryCol +''','','')')
End
-- 声明游标
DECLARE Indexs CURSOR FAST_FORWARD FOR
SELECT *
FROM #Temp_Indexs
OPEN Indexs;
-- 取第一条记录
FETCH NEXT FROM Indexs INTO @Index;
WHILE @@FETCH_STATUS=0
BEGIN
If @ICount = 0
BEGIN
Set @ConditionSql = ' Source.' + @Index + '= Target.' + @Index
Set @TypeSql = 'Target.' + @Index
END
Else
BEGIN Set @ConditionSql = @ConditionSql + ' AND Source.' + @Index + '= Target.' + @Index END
-- 取下一条记录
FETCH NEXT FROM Indexs INTO @Index;
-- 操作
Set @ICount = @ICount +1
END
-- 关闭游标
CLOSE Indexs;
-- 释放游标
DEALLOCATE Indexs;
Insert Into CompareLogHeader values(@CompareId,@CompareTime,@CompareResult,@CompareErrorCode,@CompareErrorMessage,@TableName1
,@TableName2,@CompareCol,@Excutor,0,getdate())
DECLARE @InsertDetailSql nvarchar(max)
-- 表一子查询
DECLARE @Table1Sql nvarchar(max)
-- 表二子查询
DECLARE @Table2Sql nvarchar(max)
Set @Table1Sql = 'Select * from ' + @TableName1 + ' Where 1=1 ' + @ConditionForTableName1
Set @Table2Sql = 'Select * from ' + @TableName2 + ' Where 1=1 ' + @ConditionForTableName2
Set @InsertDetailSql = N'Insert Into CompareLogDetails
Select @CompareId , ROW_NUMBER() over(order by (select 1)) as CompareItem ,' + 'case when ' + @TypeSql + ' is null then ''I'' else ''U'' end as DifferentType ,
(Select * From
(
Select * From (' + @Table1Sql + ')t
)Target
Where ' + @ConditionSql + '
For Json Path
) As TableContent1
,
(Select * From
(
Select * From (' + @Table2Sql + ')t
)Target
Where ' + @ConditionSql + '
For Json Path
)
As TableContent2 ,'+ IIF(@ReserveCol1 <> '' ,'Source.' + @ReserveCol1 + ',' , ''''',' )
+ IIF(@ReserveCol2 <> '' ,'Source.' + @ReserveCol2 + ',' , ''''',' )
+ IIF(@ReserveCol3 <> '' ,'Source.' + @ReserveCol3 + ',' , ''''',' )
+ IIF(@ReserveCol4 <> '' ,'Source.' + @ReserveCol4 + ',' , ''''',' )
+ ''''' as ExcuteSql , getDate() As InsertTime
From (
Select * From (' + @CompareSql + ')t
)Source
left join ( ' + @Table2Sql + ')Target on ' + @ConditionSql
Exec sys.sp_executesql @InsertDetailSql,N'@CompareId nvarchar(64)' ,@CompareId = @CompareId;
-- 获取数据删除的部分
-- 将表1和表2的顺序换一下
--Set @InsertDetailSql = REPLACE(@InsertDetailSql,@TableName1+' ','@TableName2 ')
--Set @InsertDetailSql = REPLACE(@InsertDetailSql,@TableName2,@TableName1)
--Set @InsertDetailSql = REPLACE(@InsertDetailSql,'@TableName2',@TableName2)
-- 将子查询换一下
Set @InsertDetailSql = REPLACE(@InsertDetailSql,@Table1Sql,'@Table2Sql')
Set @InsertDetailSql = REPLACE(@InsertDetailSql,@Table2Sql,@Table1Sql)
Set @InsertDetailSql = REPLACE(@InsertDetailSql,'@Table2Sql',@Table2Sql)
Set @InsertDetailSql = REPLACE(@InsertDetailSql,@CompareSql,@CompareSql2)
-- 将类型I 改为 D
Set @InsertDetailSql = REPLACE(@InsertDetailSql,'''I''','''D''')
-- 限制只取类型为I的类型
Set @InsertDetailSql = @InsertDetailSql + char(13)+char(10)+
' Where '+ 'case when ' + @TypeSql + ' is null then ''I'' else ''U'' end = ''I'' '
Exec sys.sp_executesql @InsertDetailSql,N'@CompareId nvarchar(64)' ,@CompareId = @CompareId;
--------------------------------
-- 4.Update Target
--------------------------------
-- 定义Merge 动态语句
If @IsUpdateDestFlg = 0
Begin
Return
End
Declare @MergeSql Nvarchar(Max)
Set @MergeSql = N'MERGE INTO ' + @TableName2 + N' Source ' + char(13)+char(10)+
N' USING ' + @TableName1 + N' Target' + char(13)+char(10)+
N' ON (' + @ConditionSql + N') ' + char(13)+char(10)+
N' WHEN MATCHED THEN ' + char(13)+char(10)
-- 定义更新\插入部分的语句
Declare @UpdateSql Nvarchar(Max)
Declare @InsertSourceSql Nvarchar(Max)
Declare @InsertTargetSql Nvarchar(Max)
Declare @Col NVARCHAR(256)
Set @ICount = 0
-- 定义临时表保存列名
create Table #Temp_Col(Col nvarchar(50))
Exec ('Insert Into #Temp_Col SELECT value FROM STRING_SPLIT('''+@CompareCol + ''', '','')')
-- 声明游标
DECLARE Cols CURSOR FAST_FORWARD FOR
SELECT *
FROM #Temp_Col
OPEN Cols;
-- 取第一条记录
FETCH NEXT FROM Cols INTO @Col;
WHILE @@FETCH_STATUS=0
BEGIN
If @ICount = 0
BEGIN
Set @UpdateSql = ' Source.' + @Col + '= Target.' + @Col
-- Set @InsertSourceSql = ' d1.' + @Col
-- Set @InsertTargetSql = ' d3.' + @Col
--Set @TypeSql = 'd3.' + @Index
END
Else
BEGIN Set @UpdateSql = @UpdateSql + ' ,Source.' + @Col + '= Target.' + @Col
-- Set @InsertSourceSql = @InsertSourceSql + ' ,d1.' + @Col
-- Set @InsertTargetSql = @InsertTargetSql + ' ,d3.' + @Col
END
-- 取下一条记录
FETCH NEXT FROM Cols INTO @Col;
-- 操作
Set @ICount = @ICount +1
END
-- 关闭游标
CLOSE Cols;
-- 释放游标
DEALLOCATE Cols;
-- 将更新、插入逻辑加到Merge 逻辑中
Set @MergeSql = @MergeSql + N' UPDATE SET ' + char(13)+char(10)+
@UpdateSql + char(13)+char(10)+
N' WHEN NOT MATCHED THEN ' + char(13)+char(10)+
N'Insert VALUES ('
+ char(13)+char(10)+ @CompareCol
+ N',getdate(),getdate(),'''''
+ N' )'+ char(13)+char(10)+
+ 'When Not Matched By Source '+ char(13)+char(10)+
+ 'THEN DELETE ;';
-- 更新目标表
Exec( @MergeSql)