Сравнение схем MSSQL с помощью T SQL
У меня есть 21 БД на том же сервере, которые "должны" иметь ту же схему (ограничивающую схему только схемой таблицы на данный момент), но они этого не делают. В среде, где я нахожусь, я не могу установить какой-либо инструмент / приложения согласно правилам соответствия. Единственный способ, которым я могу придумать, - это проверить схему всех 21 БД в Excel и сравнить, но это утомительно.
Может ли кто-нибудь помочь мне в разработке T-SQL, который может сравнить схему для всех 21 БД и выделить различия?
Это нужные мне столбцы: имя_таблицы, имя столбца, тип данных, максимальная длина, is_nullable, is_replicated, первичный ключ
Следующий T-SQL поднимает это в информации для меня. Мне нужно некоторое представление о том, как я могу сравнить эту информацию для 21 БД
SELECT a.name Table_Name, c.name 'Column Name',
t.Name 'Data type',
c.max_length 'Max Length',
c.is_nullable,a.is_replicated ,
ISNULL(i.is_primary_key, 0) 'Primary Key'
FROM Sys.tables a inner join sys.columns c
On A.object_id=C.object_id
INNER JOIN
sys.types t ON c.user_type_id = t.user_type_id
LEFT OUTER JOIN
sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
LEFT OUTER JOIN
sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
Order by 1,2
Мне нужна отправная точка
1 ответ
Мне приходится все время делать подобные вещи в одинаковых условиях, в том числе без использования профессиональных инструментов, разработанных для этого. Вот один из способов:
Сначала создайте временную таблицу для хранения информации о таблице:
CREATE TABLE #DbSchemas(
DbName nvarchar(128) NULL,
Table_Name sysname NOT NULL,
[Column Name] sysname NULL,
[Data type] sysname NOT NULL,
[Max Length] smallint NOT NULL,
is_nullable bit NULL,
is_replicated bit NULL,
[Primary Key] bit NOT NULL
)
GO
Затем включите запрос, который у вас уже есть, в недокументированную системную процедуру. sp_MSforeachdb
выполнить его в каждой базе данных, добавив результаты в таблицу #DbSchemas:
EXECUTE master.sys.sp_MSforeachdb 'USE [?];
INSERT INTO #DbSchemas
SELECT DB_NAME() DbName, a.name Table_Name, c.name [Column Name],
t.Name [Data type],
c.max_length [Max Length],
c.is_nullable,a.is_replicated ,
ISNULL(i.is_primary_key, 0) [Primary Key]
FROM Sys.tables a inner join sys.columns c
On A.object_id=C.object_id
INNER JOIN
sys.types t ON c.user_type_id = t.user_type_id
LEFT OUTER JOIN
sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
LEFT OUTER JOIN
sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
Order by 1,2
;
';
go
Теперь вы должны иметь возможность запрашивать данные из любой базы данных в таблице #DbSchemas:
select * from #DbSchemas where Dbname = 'master'
Наконец, чтобы сравнить их, вы можете использовать что-то вроде этого:
SELECT * FROM #DbSchemas s1
WHERE DbName = 'msdb'
AND NOT EXISTS(
SELECT * FROM #DbSchemas s2
WHERE s2.DbName = 'master'
AND s2.Table_Name = s1.Table_Name
AND s2.[Column Name] = s1.[Column Name]
AND s2.[Data type] = s1.[Data type]
AND s2.[Max length] = s1.[Max length]
AND s2.is_nullable = s1.is_nullable
AND s2.is_replicated = s1.is_replicated
AND s2.[Primary Key] = s1.[Primary Key]
)