/*
Compare master table data on 2 servers (
1. Change server name
2. Set RaceDate (@racedate) with the >, < ,= >= operator
before you run)
--KNOWN ISSUES
1. Tables need PKs
*/
SET NOCOUNT ON
--Destination Server Details
DECLARE @destServ nvarchar(40)='[sql\inst23]' --required -- If local instance, leave the string empty
DECLARE @destdb nvarchar(40)='DBName' --required
DECLARE @destSchema nvarchar(40)='dbo' --required
DECLARE @destTable nvarchar(40)='TableName' --required
-- Source Server Details
DECLARE @SourServ nvarchar(40)='[sql\inst07]' --required
DECLARE @Sourdb nvarchar(40)='DBonRemoteServer' --required
DECLARE @SourSchema nvarchar(40)='dbo' --required
DECLARE @SourTable nvarchar(40)='TableName' --required -- TableName format 'MyTable'
DECLARE @WHERE nvarchar(400) = 'WHERE 1=1'
DECLARE @Clause nvarchar(400)= 'AND Id > 201808201500000' --Choose a Predicate to limit data --Start with AND . e.g: 'AND Date > ''20180801'' '
SELECT @WHERE = @WHERE + @Clause
DECLARE @randomtablesuffix nvarchar(5)
SELECT @randomtablesuffix= SUBSTRING(CAST(NEWID() as nvarchar(255)),1,5)
declare @v nvarchar(max), @sql nvarchar(max), @retval nvarchar(max) , @ParamDef nvarchar(400)
--GET Columns List as varchar Columns for HASHBYTES to compare
SELECT @sql='SELECT @vv= COALESCE(@vv,'''')+''CAST(ISNULL(''+ COLUMN_NAME + '',0) as VARCHAR(''+
CASE WHEN DATA_TYPE IN (''varchar'',''nvarchar'') THEN CAST(CHARACTER_MAXIMUM_LENGTH as varchar(5)) ELSE ''60 '' END +'')) + ''
from '+ @destdb + '.INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='+ QUOTENAME(@destTable,'''') + ''
SET @ParamDef = N'@vv nvarchar(max) OUTPUT'
EXEC sp_executesql @sql, @ParamDef, @vv=@v OUTPUT;
SELECT @v= SUBSTRING(@v,0,LEN(@v))
--Keys to JOIN
DECLARE @pkeylistJoinOUT nvarchar(4000)=''
SET @sql='SELECT @pkeylistJoin = ISNULL(@pkeylistJoin,'''') + '' a.''+ QUOTENAME(COLUMN_NAME) + ''=b.''+ QUOTENAME(COLUMN_NAME) + '' AND''
FROM '+@destdb+'.[INFORMATION_SCHEMA].[KEY_COLUMN_USAGE]
WHERE TABLE_NAME='+ QUOTENAME(@destTable,'''') + ' ORDER BY ORDINAL_POSITION'
SET @ParamDef = N'@pkeylistJoin nvarchar(max) OUTPUT'
EXEC sp_executesql @sql, @ParamDef, @pkeylistJoin=@pkeylistJoinOUT OUTPUT;
SELECT @pkeylistJoinOUT = REPLACE(REPLACE(REVERSE( SUBSTRING(REVERSE(@pkeylistJoinOUT), CHARINDEX(']', REVERSE(@pkeylistJoinOUT)), LEN(@pkeylistJoinOUT)) ),']',''),'[','')
--Get Column List
DECLARE @ColumnListOut nvarchar(max)=''
SET @sql='SELECT @ColumnList=ISNULL(@ColumnList,'''') + COLUMN_NAME + '','' FROM '+@destdb +'.[INFORMATION_SCHEMA].[COLUMNS] WHERE TABLE_NAME='+QUOTENAME(@destTable,'''')+ ' ORDER BY ORDINAL_POSITION'
SET @ParamDef = N'@ColumnList nvarchar(max) OUTPUT'
EXEC sp_executesql @sql, @ParamDef, @ColumnList=@ColumnListOut OUTPUT;
SET @ColumnListOut=SUBSTRING(@ColumnListOut,0,LEN(@ColumnListOut))
--Now Compare
SELECT @sql='
SELECT a.* INTO ##_destissues'+@randomtablesuffix+' FROM (
SELECT HASHBYTES (''SHA2_512'','+ @v +')HashVal,'+ @ColumnListOut +' FROM '+@destServ+'.'+@destdb+'.'+@destSchema+'.'+@destTable + ' x WITH (NOLOCK) ' + @WHERE + '
)a
JOIN (
SELECT HASHBYTES (''SHA2_512'','+@v +')HashVal,'+ @ColumnListOut + ' FROM ' +@SourServ +'.'+ @Sourdb+ '.'+@SourSchema+'.'+ @SourTable +' y WITH (NOLOCK) ' + @WHERE + '
)
b ON '+@pkeylistJoinOUT + ' AND a.HashVal <> b.HashVal '
--print @sql
exec (@sql)
SELECT @sql='
SELECT b.* INTO ##_sourceissues'+@randomtablesuffix+ ' FROM (
SELECT HASHBYTES (''SHA2_512'','+ @v +')HashVal,'+ @ColumnListOut +' FROM '+@destServ+'.'+@destdb+'.'+@destSchema+'.'+@destTable + ' x WITH (NOLOCK) ' + @WHERE + '
)a
JOIN (
SELECT HASHBYTES (''SHA2_512'','+@v +')HashVal,'+ @ColumnListOut + ' FROM ' +@SourServ +'.'+ @Sourdb+ '.'+@SourSchema+'.'+ @SourTable +' y WITH (NOLOCK) ' + @WHERE + '
)
b ON '+@pkeylistJoinOUT + ' AND a.HashVal <> b.HashVal '
exec (@sql)
--Get Column List for Pivoting
DECLARE @ColumnListOutasVC nvarchar(max)=''
SET @sql='SELECT @ColumnList=ISNULL(@ColumnList,'''')+ ''CAST(''+ COLUMN_NAME + '' AS VARCHAR(200)) as ''+ COLUMN_NAME + '','' FROM ' + @destdb+'.[INFORMATION_SCHEMA].[COLUMNS] WHERE TABLE_NAME='+QUOTENAME(@desttable,'''')
SET @ParamDef = N'@ColumnList nvarchar(max) OUTPUT'
EXEC sp_executesql @sql, @ParamDef, @ColumnList=@ColumnListOutasVC OUTPUT;
SET @ColumnListOutasVC=SUBSTRING(@ColumnListOutasVC,0,LEN(@ColumnListOutasVC))
--Get PKs as VARCHAR Values
DECLARE @pkeylistJoinOUTVC nvarchar(4000)=''
SET @sql='SELECT @pkeylistJoin = ISNULL(@pkeylistJoin,'''') + ''CAST(''+COLUMN_NAME + '' as varchar(200)) as '' + COLUMN_NAME + ''1,'' FROM '+ @destdb+'.[INFORMATION_SCHEMA].[KEY_COLUMN_USAGE] WHERE TABLE_NAME='+QUOTENAME(@destTable,'''') + ' ORDER BY ORDINAL_POSITION'
SET @ParamDef = N'@pkeylistJoin nvarchar(max) OUTPUT'
EXEC sp_executesql @sql, @ParamDef, @pkeylistJoin=@pkeylistJoinOUTVC OUTPUT;
SET @pkeylistJoinOUTVC=SUBSTRING(@pkeylistJoinOUTVC,0,LEN(@pkeylistJoinOUTVC))
--SELECT @pkeylistJoinOUTVC
SET @sql='
select * INTO ##_destissuedetail'+@randomtablesuffix+ ' from(
select '+ @pkeylistJoinOUTVC + ', ' + @ColumnListOutasVC
+ '
from
##_destissues'+ @randomtablesuffix+ '
)c UNPIVOT
(
Vals for ColNames in ('+@ColumnListOut+')
) d'
EXEC( @sql)
SET @sql='
select * INTO ##_sourceissuedetail'+@randomtablesuffix+' from(
select '+ @pkeylistJoinOUTVC + ', ' + @ColumnListOutasVC
+ '
from
##_sourceissues'+ @randomtablesuffix+'
)c UNPIVOT
(
Vals for ColNames in ('+@ColumnListOut+')
) d'
EXEC( @sql)
SELECT 'Tables to look for data are ##_destissuedetail'+@randomtablesuffix +' and ##_sourceissuedetail ' +@randomtablesuffix
SET @sql='
SELECT * FROM ##_destissuedetail'+@randomtablesuffix+ '
EXCEPT
SELECT * FROM ##_sourceissuedetail' +@randomtablesuffix
EXEC (@sql)
Skrip (bila diberikan dengan detail yang relevan) membandingkan 2 tabel (mis. Pelanggan di server1 ke Pelanggan di Server2).
Script ini akan berguna jika Anda membandingkan tabel dengan banyak kolom tetapi berjuang untuk menemukan kolom ketidakcocokan yang tepat.
Saya memiliki tabel dengan 353 kolom dan saya harus membandingkannya dengan tabel lain dan menemukan dengan nilai tidak cocok dan skrip ini akan membantu Anda menemukan tuple yang tepat.