Сравнение схем 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]
      )
Другие вопросы по тегам