1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
| DECLARE @SQL NVARCHAR(MAX); DECLARE @CountSQL NVARCHAR(MAX); DECLARE @TableName NVARCHAR(128); DECLARE @SchemaName NVARCHAR(128); DECLARE @RecordCount BIGINT; DECLARE @HasPK BIT; DECLARE @PKColumns NVARCHAR(MAX); DECLARE @MaxRows INT = 1000; DECLARE @DataSize INT = 4000;
IF OBJECT_ID('tempdb..#TableHashes') IS NOT NULL DROP TABLE #TableHashes;
CREATE TABLE #TableHashes ( SchemaName NVARCHAR(128), TableName NVARCHAR(128), TableHash VARBINARY(20), RecordCount BIGINT, UsedPK BIT, ErrorMessage NVARCHAR(MAX) NULL );
DECLARE TableCursor CURSOR FOR SELECT s.name AS SchemaName, t.name AS TableName FROM sys.tables t INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
OPEN TableCursor; FETCH NEXT FROM TableCursor INTO @SchemaName, @TableName;
WHILE @@FETCH_STATUS = 0 BEGIN SET @CountSQL = N'SELECT @RecordCount = COUNT(*) FROM ' + QUOTENAME(@SchemaName) + '.' + QUOTENAME(@TableName); EXEC sp_executesql @CountSQL, N'@RecordCount BIGINT OUTPUT', @RecordCount OUTPUT; SET @HasPK = 0; SET @PKColumns = NULL; SELECT @HasPK = 1, @PKColumns = STUFF(( SELECT ', ' + QUOTENAME(c.name) FROM sys.indexes i INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id WHERE i.object_id = OBJECT_ID(@SchemaName + '.' + @TableName) AND i.is_primary_key = 1 ORDER BY ic.key_ordinal FOR XML PATH('') ), 1, 2, '') FROM sys.indexes i WHERE i.object_id = OBJECT_ID(@SchemaName + '.' + @TableName) AND i.is_primary_key = 1; IF @RecordCount = 0 BEGIN INSERT INTO #TableHashes (SchemaName, TableName, TableHash, RecordCount, UsedPK, ErrorMessage) VALUES (@SchemaName, @TableName, HASHBYTES('SHA1', ''), 0, @HasPK, NULL); END ELSE BEGIN IF @HasPK = 1 BEGIN SET @SQL = N' INSERT INTO #TableHashes (SchemaName, TableName, TableHash, RecordCount, UsedPK, ErrorMessage) SELECT ''' + @SchemaName + ''', ''' + @TableName + ''', HASHBYTES(''SHA1'', SUBSTRING((SELECT TOP ' + CAST(@MaxRows AS NVARCHAR(10)) + ' ' + @PKColumns + ' FROM ' + QUOTENAME(@SchemaName) + '.' + QUOTENAME(@TableName) + ' ORDER BY ' + @PKColumns + ' FOR XML RAW, BINARY BASE64), 1, ' + CAST(@DataSize AS NVARCHAR(10)) + ')), ' + CAST(@RecordCount AS NVARCHAR(20)) + ', 1, NULL'; END ELSE BEGIN SET @SQL = N' INSERT INTO #TableHashes (SchemaName, TableName, TableHash, RecordCount, UsedPK, ErrorMessage) SELECT ''' + @SchemaName + ''', ''' + @TableName + ''', HASHBYTES(''SHA1'', SUBSTRING((SELECT TOP ' + CAST(@MaxRows AS NVARCHAR(10)) + ' * FROM ' + QUOTENAME(@SchemaName) + '.' + QUOTENAME(@TableName) + ' FOR XML RAW, BINARY BASE64), 1, ' + CAST(@DataSize AS NVARCHAR(10)) + ')), ' + CAST(@RecordCount AS NVARCHAR(20)) + ', 0, NULL'; END BEGIN TRY EXEC sp_executesql @SQL; END TRY BEGIN CATCH PRINT '錯誤處理表格: ' + @SchemaName + '.' + @TableName; INSERT INTO #TableHashes (SchemaName, TableName, TableHash, RecordCount, UsedPK, ErrorMessage) VALUES (@SchemaName, @TableName, NULL, @RecordCount, @HasPK, ERROR_MESSAGE()); END CATCH END
FETCH NEXT FROM TableCursor INTO @SchemaName, @TableName; END
CLOSE TableCursor; DEALLOCATE TableCursor;
SELECT SchemaName, TableName, CONVERT(VARCHAR(40), TableHash, 2) AS TableHashHex, RecordCount, CASE WHEN UsedPK = 1 THEN 'Yes' ELSE 'No' END AS UsedPrimaryKey, CASE WHEN TableHash IS NULL THEN 'Failed to calculate hash' ELSE 'Success' END AS Status, ErrorMessage FROM #TableHashes ORDER BY SchemaName, TableName;
DROP TABLE #TableHashes;
|