I am trying to run a SQL Server export which compares the table names listed in three or more databases on a SQL Server instance (actually the number is a lot higher!)
I can use something simple like the following to get a list of all of the tables in a particular database.
SELECT [name]
FROM DB1.sys.tables
What I would like to be able to do is to be able to join these for multiple databases to create a single view to spot differences (and similarities).
So for example if I have three databases with the following tables
DB1:
Customers
Orders
Products
DB2:
Products
Orders
DB3:
Products
Suppliers
How could I join them all together to get something like the following?
DB1 | DB2 | DB3 |
---|---|---|
Customers | NULL | NULL |
Orders | Orders | NULL |
Products | Products | Products |
NULL | NULL | Suppliers |
Thanks!
This script should give you what you are looking for and can be easily extended by fiddling with the WHERE clause around line 20
--Set up some global temporary tables
CREATE TABLE ##all_tables(
[database_name] sysname,
[table_name] sysname
)
CREATE TABLE ##tables_for_relevant_dbs(
[database_name] sysname,
[table_name] sysname
)
--Capture a list of all the tables in all of the databases on the instance
exec sp_MSforeachdb 'insert into ##all_tables select ''?'', [name] from [?].sys.tables'
--Filter to get the tables from the relevant databases
INSERT INTO ##tables_for_relevant_dbs
SELECT dbs.[database_name],tbls.[table_name]
FROM (select distinct database_name from ##all_tables) dbs
LEFT JOIN ##all_tables tbls on tbls.database_name=dbs.database_name
WHERE dbs.database_name like '%' --PUT SOMETHING ELSE HERE
--This magic TSQL concatenates a column of values into a single string
--This string is then used in the dynamic pivoting below
DECLARE @dblist VARCHAR(MAX)
SELECT
@dblist = STUFF((SELECT ', [' + d_name + ']' AS [text()]
FROM (SELECT DISTINCT
database_name d_name
FROM ##tables_for_relevant_dbs) d
ORDER BY d_name
FOR XML PATH('')), 1, 1, '')
--Pivot the data to turn the database names into columns
EXEC ('SELECT ' + @dblist + '
FROM (SELECT at1.database_name, at2.table_name src, at1.table_name dest
FROM ##tables_for_relevant_dbs at1
LEFT JOIN ##tables_for_relevant_dbs at2 on at2.database_name=at1.database_name and at2.table_name=at1.table_name) t
PIVOT (max(t.src) FOR [database_name] IN (' + @dblist + ')) as [PVT]')
--Clean up
DROP TABLE ##all_tables
DROP TABLE ##tables_for_relevant_dbs