-
Notifications
You must be signed in to change notification settings - Fork 37
Expand file tree
/
Copy pathTsqlTools-SQLcompare-IndexCompare.sql
More file actions
153 lines (127 loc) · 5.04 KB
/
TsqlTools-SQLcompare-IndexCompare.sql
File metadata and controls
153 lines (127 loc) · 5.04 KB
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*****************************************************************
-----------------------
tsqltools - SQLCOMPARE - Index Compare
-----------------------
Version: v1.0
Release Date: 2017-07-30
Author: Bhuvanesh(@SQLadmin)
Feedback: mailto:r.bhuvanesh@outlook.com
Updates: http://medium.com/sqladmin
Repo: https://github.com/SqlAdmin/tsqltools/
License:
tsqltools is free to download.It contains Tsql stored procedures
and scripts to help the DBAs and Developers to make their job easier
(C) 2017
======================================================================
What is TsqlTools-SQLcompare?
TsqlTools-SQLcompare is a tsqlscript that will help to compare Databases,
Tables, Objects, Indexices between two servers without any tools.
======================================================================
How to Start?
Use a centalized server and create LinkedServers from the centralized server.
Or Create LinkedServer on SourceDB server then run this query on SourceDB server.
========================================================================*/
-- Declare necessary variables
DECLARE @SourceDbServer NVARCHAR(100) = '[db01]'; -- Replace with your source DB server name
DECLARE @DestinationDbServer NVARCHAR(100) = '[db02]'; -- Replace with your target DB server name
DECLARE @SourceDbNameQuery NVARCHAR(MAX);
DECLARE @DestinationDbNameQuery NVARCHAR(MAX);
-- Declare table variables to store database names
DECLARE @SourceDatabases TABLE (DbName NVARCHAR(100));
DECLARE @DestinationDatabases TABLE (DbName NVARCHAR(100));
-- Populate source database names
SET @SourceDbNameQuery = N'SELECT name FROM ' + @SourceDbServer + '.master.sys.databases WHERE database_id > 4';
INSERT INTO @SourceDatabases
EXEC sp_executesql @SourceDbNameQuery;
-- Populate destination database names
SET @DestinationDbNameQuery = N'SELECT name FROM ' + @DestinationDbServer + '.master.sys.databases WHERE database_id > 4';
INSERT INTO @DestinationDatabases
EXEC sp_executesql @DestinationDbNameQuery;
-- Temporary tables to store index information
CREATE TABLE #SourceDbIndexes (
DbName NVARCHAR(100),
TableName NVARCHAR(500),
IndexName NVARCHAR(300),
IndexType NVARCHAR(100)
);
CREATE TABLE #DestinationDbIndexes (
DbName NVARCHAR(100),
TableName NVARCHAR(500),
IndexName NVARCHAR(300),
IndexType NVARCHAR(100)
);
-- Cursor to iterate through source databases
DECLARE dbCursor CURSOR FOR
SELECT DbName FROM @SourceDatabases;
OPEN dbCursor;
DECLARE @SourceDbName NVARCHAR(100);
FETCH NEXT FROM dbCursor INTO @SourceDbName;
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @SourceSql NVARCHAR(MAX) = '
INSERT INTO #SourceDbIndexes
SELECT ''' + @SourceDbName + ''',
so.name AS TableName,
si.name AS IndexName,
si.type_desc AS IndexType
FROM ' + @SourceDbServer + '.' + @SourceDbName + '.sys.indexes si
JOIN ' + @SourceDbServer + '.' + @SourceDbName + '.sys.objects so
ON si.object_id = so.object_id
WHERE so.type = ''U'' AND si.name IS NOT NULL
ORDER BY so.name, si.type';
EXEC sp_executesql @SourceSql;
FETCH NEXT FROM dbCursor INTO @SourceDbName;
END;
CLOSE dbCursor;
DEALLOCATE dbCursor;
-- Cursor to iterate through destination databases
DECLARE dbCursor CURSOR FOR
SELECT DbName FROM @DestinationDatabases;
OPEN dbCursor;
DECLARE @DestinationDbName NVARCHAR(100);
FETCH NEXT FROM dbCursor INTO @DestinationDbName;
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @DestinationSql NVARCHAR(MAX) = '
INSERT INTO #DestinationDbIndexes
SELECT ''' + @DestinationDbName + ''',
so.name AS TableName,
si.name AS IndexName,
si.type_desc AS IndexType
FROM ' + @DestinationDbServer + '.' + @DestinationDbName + '.sys.indexes si
JOIN ' + @DestinationDbServer + '.' + @DestinationDbName + '.sys.objects so
ON si.object_id = so.object_id
WHERE so.type = ''U'' AND si.name IS NOT NULL
ORDER BY so.name, si.type';
EXEC sp_executesql @DestinationSql;
FETCH NEXT FROM dbCursor INTO @DestinationDbName;
END;
CLOSE dbCursor;
DEALLOCATE dbCursor;
-- Compare indexes and output status
WITH SourceIndexHash AS (
SELECT DbName, TableName, IndexName,
HASHBYTES('SHA1', CONCAT(DbName, TableName, IndexName)) AS IndexHash
FROM #SourceDbIndexes
),
DestinationIndexHash AS (
SELECT DbName, TableName, IndexName,
HASHBYTES('SHA1', CONCAT(DbName, TableName, IndexName)) AS IndexHash
FROM #DestinationDbIndexes
)
SELECT
COALESCE(s.DbName, d.DbName) AS DbName,
COALESCE(s.TableName, d.TableName) AS TableName,
COALESCE(s.IndexName, d.IndexName) AS IndexName,
CASE
WHEN s.IndexHash IS NULL THEN 'Available On ' + @DestinationDbServer + ' Only'
WHEN d.IndexHash IS NULL THEN 'Available On ' + @SourceDbServer + ' Only'
ELSE 'Available On Both Servers'
END AS Status
FROM SourceIndexHash s
FULL JOIN DestinationIndexHash d
ON s.IndexHash = d.IndexHash
ORDER BY TableName;
-- Clean up temporary tables
DROP TABLE #SourceDbIndexes;
DROP TABLE #DestinationDbIndexes;