/*
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)
Das Skript vergleicht (sofern mit den relevanten Details versehen) 2 Tabellen (z. B. Kunden auf Server1 mit Kunden auf Server2).
Dieses Skript ist nützlich, wenn Sie eine Tabelle mit vielen Spalten vergleichen, aber Schwierigkeiten haben, die genaue Spalte mit der falschen Zuordnung zu finden.
Ich habe eine Tabelle mit 353 Spalten und musste sie mit einer anderen Tabelle vergleichen und feststellen, dass die Werte nicht übereinstimmen. Dieses Skript hilft Ihnen dabei, das genaue Tupel zu finden.