在开发过程中,有时我们会碰到需要对比数据的情况,但又因为需要对比的数据表结构过于复杂,例如一张表可能会有六七十个字段,这时候我们去排查两条数据的差异时,就会耗费大量的时间和精力,而且失误的几率也比较高,那么我在想,能不能写个脚本直接拉取两条数据有差异的字段。
1.首先我们获取到【数据所在表】的所有字段并存入一张临时表
--表名
DECLARE @MaintableName NVARCHAR(100) = '数据所在表'
SELECT
sysobjects.name TableName,
syscolumns.name ColumnsName
INTO #MainTable
FROM sysobjects
inner join syscolumns
ON sysobjects.id =syscolumns.id --表关联条件
where sysobjects.name= @MaintableName
2.然后写入能够查出需要对比的数据的条件并创建一张可以用于保存差异字段名的临时表
--查出两条差异数据的条件
DECLARE @strConditions NVARCHAR(1000) = ' 查出两条差异数据的条件 '
--不重复的字段
CREATE TABLE #notRepeatColumnsTable (
ColumnsName NVARCHAR(50)
)
3.使用游标循环刚才创建的 【数据所在表】的所有字段 的临时表 #MainTable
DECLARE @TableName NVARCHAR(500) , @ColumnsName NVARCHAR(500) --声明变量,需要读取的数据
DECLARE cur CURSOR
FOR
SELECT TableName,ColumnsName FROM #MainTable
OPEN cur --打开游标
FETCH NEXT FROM cur INTO @TableName, @ColumnsName --取数据
WHILE ( @@fetch_status = 0 ) --判断是否还有数据
BEGIN
DECLARE @strSql NVARCHAR(2000)= '
DECLARE @isRepeat INT ,@itemColumnsName nvarchar(50)
select @isRepeat = count(isnull('+@ColumnsName+',0)) from '+@TableName+' where '+@strConditions +' group by '+ @ColumnsName +'
IF(@isRepeat <> 2)
insert #notRepeatColumnsTable values('''+@ColumnsName+''' )
'
EXEC (@strSql)
FETCH NEXT FROM cur INTO @TableName, @ColumnsName --取下一条数据
END
CLOSE cur --关闭游标
DEALLOCATE cur
4.查询用于储存差异字段的表并删除临时表
SELECT * FROM #notRepeatColumnsTable
drop table #MainTable,#notRepeatColumnsTable
至此就拿到了两条数据有差异的字段名
为了方便大家复制,以下是完整代码:
--表名
DECLARE @MaintableName NVARCHAR(100) = '需要对比数据的表名'
SELECT
sysobjects.name TableName,
syscolumns.name ColumnsName
INTO #MainTable
FROM sysobjects
inner join syscolumns
ON sysobjects.id =syscolumns.id --表关联条件
where sysobjects.name= @MaintableName
--查出两条差异数据的条件
DECLARE @strConditions NVARCHAR(1000) = ' 查出两条差异数据的条件 '
--不重复的字段
CREATE TABLE #notRepeatColumnsTable (
ColumnsName NVARCHAR(50)
)
DECLARE @TableName NVARCHAR(500) , @ColumnsName NVARCHAR(500) --声明变量,需要读取的数据
DECLARE cur CURSOR
FOR
SELECT TableName,ColumnsName FROM #MainTable
OPEN cur --打开游标
FETCH NEXT FROM cur INTO @TableName, @ColumnsName --取数据
WHILE ( @@fetch_status = 0 ) --判断是否还有数据
BEGIN
DECLARE @strSql NVARCHAR(2000)= '
DECLARE @isRepeat INT ,@itemColumnsName nvarchar(50)
select @isRepeat = count(isnull('+@ColumnsName+',0)) from '+@TableName+' where '+@strConditions +' group by '+ @ColumnsName +'
--这里根据需求可以根据你的数据条数进行修改,也可以直接Print出字段便于复制
IF(@isRepeat <> 2)
insert #notRepeatColumnsTable values('''+@ColumnsName+''' )
/*
IF(@isRepeat <> 2)
print ('''+@ColumnsName+','' )
*/
'
EXEC (@strSql)
FETCH NEXT FROM cur INTO @TableName, @ColumnsName --取下一条数据
END
CLOSE cur --关闭游标
DEALLOCATE cur
--使用Print可以注释掉这条语句
SELECT * FROM #notRepeatColumnsTable
drop table #MainTable,#notRepeatColumnsTable
本来我是打算连同差异数据也一起拉出来,但目前还没有什么好的办法实现。