Chúng tôi đang thực hiện một quy trình ETL. Khi tất cả được nói và thực hiện, có một loạt các bảng nên giống hệt nhau. Cách nhanh nhất để xác minh rằng các bảng đó (trên hai máy chủ khác nhau) trên thực tế là giống hệt nhau. Tôi đang nói cả lược đồ và dữ liệu.
Tôi có thể thực hiện băm trên bàn không, giống như tôi có thể vào một tệp riêng lẻ hoặc nhóm fileg - để so sánh cái này với cái kia. Chúng tôi có so sánh dữ liệu Cổng Đỏ nhưng vì các bảng trong câu hỏi chứa hàng triệu hàng mỗi nên tôi muốn một cái gì đó hiệu quả hơn một chút.
Một cách tiếp cận khiến tôi tò mò là cách sử dụng sáng tạo này của tuyên bố công đoàn . Nhưng, tôi muốn khám phá ý tưởng băm xa hơn một chút nếu có thể.
BÀI ĐĂNG CẬP NHẬT
Đối với bất kỳ khách hàng tiềm năng nào trong tương lai ... đây là cách tiếp cận chính xác mà tôi đã thực hiện. Nó hoạt động rất tốt, chúng tôi đang thực hiện nó trên mỗi bảng trong mỗi cơ sở dữ liệu. Cảm ơn câu trả lời dưới đây đã chỉ cho tôi đi đúng hướng.
CREATE PROCEDURE [dbo].[usp_DatabaseValidation]
@TableName varchar(50)
AS
BEGIN
SET NOCOUNT ON;
-- parameter = if no table name was passed do them all, otherwise just check the one
-- create a temp table that lists all tables in target database
CREATE TABLE #ChkSumTargetTables ([fullname] varchar(250), [name] varchar(50), chksum int);
INSERT INTO #ChkSumTargetTables ([fullname], [name], [chksum])
SELECT DISTINCT
'[MyDatabase].[' + S.name + '].['
+ T.name + ']' AS [fullname],
T.name AS [name],
0 AS [chksum]
FROM MyDatabase.sys.tables T
INNER JOIN MyDatabase.sys.schemas S ON T.schema_id = S.schema_id
WHERE
T.name like IsNull(@TableName,'%');
-- create a temp table that lists all tables in source database
CREATE TABLE #ChkSumSourceTables ([fullname] varchar(250), [name] varchar(50), chksum int)
INSERT INTO #ChkSumSourceTables ([fullname], [name], [chksum])
SELECT DISTINCT
'[MyLinkedServer].[MyDatabase].[' + S.name + '].['
+ T.name + ']' AS [fullname],
T.name AS [name],
0 AS [chksum]
FROM [MyLinkedServer].[MyDatabase].sys.tables T
INNER JOIN [MyLinkedServer].[MyDatabase].sys.schemas S ON
T.schema_id = S.schema_id
WHERE
T.name like IsNull(@TableName,'%');;
-- build a dynamic sql statement to populate temp tables with the checksums of each table
DECLARE @TargetStmt VARCHAR(MAX)
SELECT @TargetStmt = COALESCE(@TargetStmt + ';', '')
+ 'UPDATE #ChkSumTargetTables SET [chksum] = (SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM '
+ T.FullName + ') WHERE [name] = ''' + T.Name + ''''
FROM #ChkSumTargetTables T
SELECT @TargetStmt
DECLARE @SourceStmt VARCHAR(MAX)
SELECT @SourceStmt = COALESCE(@SourceStmt + ';', '')
+ 'UPDATE #ChkSumSourceTables SET [chksum] = (SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM '
+ S.FullName + ') WHERE [name] = ''' + S.Name + ''''
FROM #ChkSumSourceTables S
-- execute dynamic statements - populate temp tables with checksums
EXEC (@TargetStmt);
EXEC (@SourceStmt);
--compare the two databases to find any checksums that are different
SELECT TT.FullName AS [TABLES WHOSE CHECKSUM DOES NOT MATCH]
FROM #ChkSumTargetTables TT
LEFT JOIN #ChkSumSourceTables ST ON TT.Name = ST.Name
WHERE IsNull(ST.chksum,0) <> IsNull(TT.chksum,0)
--drop the temp tables from the tempdb
DROP TABLE #ChkSumTargetTables;
DROP TABLE #ChkSumSourceTables;
END