Como posso comparar o esquema de dois bancos de dados?

19

Existe uma maneira de encontrar as diferenças nos dois bancos de dados do SQL Server (somente esquema). Um é local e o segundo no site do cliente. Estamos com problemas com relatórios de cristal executando alguns relatórios e algum código não sendo executado e parece que os esquemas não correspondem.

Posso executar o mesmo comando nos dois bancos de dados e comparar os resultados para saber onde estão as diferenças?

user1571430
fonte
Esta pergunta sobre o SO tem algumas boas sugestões.
LowlyDBA

Respostas:

13

Se você não puder usar uma das muitas ferramentas disponíveis por causa de problemas de conectividade e desejar uma comparação "offline", poderá usar o SSMS para gerar scripts para todos os objetos de banco de dados clicando com o botão direito do mouse no banco de dados e usando as "Tarefas ... / Gerar Scripts ", e certifique-se de selecionar criar um arquivo por objeto.

Quando você fizer isso para os dois bancos de dados, coloque os dois conjuntos de scripts em uma máquina local em duas pastas separadas e use o WinMerge (ou similar) para comparar os dois.

Senhor Magoo
fonte
6

Outra opção é usar o SSDT (SQL Server Data Tools), uma extensão do Visual Studio. Você pode extrair o esquema do banco de dados como um arquivo .dacpac e compará-lo com outro arquivo .dacpac ou com um banco de dados existente. O SSDT está incluído nas ferramentas de cliente do SQL Server 2012, tornando-o bastante acessível. Você pode encontrar as instruções completas de como executar a comparação no site do MSDN .

Mike Fal
fonte
6

Depois de lutar com uma maneira fácil de fazer a mesma tarefa - veja o que mudou entre dois modelos, escrevi o seguinte script SQL que comparará dois esquemas para determinar colunas novas e excluídas

set nocount on;
-- Set the two variables newmodel and oldmodel to the appropriate database names and execute the script

declare @newmodel varchar(50), @oldmodel varchar(50);

Set @newmodel = '[NewModel to Compare]';
set @oldmodel = '[OldModel to Compare]';


Declare @Temp table (TABLE_SCHEMA varchar(40), TABLE_NAME varchar(40), COLUMN_NAME varchar(50), ORDINAL_POSITION int, IS_NULLABLE varchar(5), NullChange varchar(5), Comment varchar(50));

Declare @script varchar(5000);


set @script = '
Select nc.TABLE_SCHEMA, nc.TABLE_NAME, nc.COLUMN_NAME, nc.ORDINAL_POSITION, nc.IS_NULLABLE, IIF(nc.IS_NULLABLE <> oc.IS_NULLABLE, ''Yes'', ''No''), 
        IIF(oc.COLUMN_NAME IS NULL, convert(varchar(20), ''ADDED COLUMN''), convert(varchar(20), ''--'')) as Comment
    from {NEW}.INFORMATION_SCHEMA.COLUMNS nc
        LEFT join {OLD}.INFORMATION_SCHEMA.COLUMNS oc 
            on nc.TABLE_NAME = oc.TABLE_NAME and nc.COLUMN_NAME = oc.COLUMN_NAME
UNION ALL
    Select oc.TABLE_SCHEMA, oc.TABLE_NAME, oc.COLUMN_NAME, oc.ORDINAL_POSITION, oc.IS_NULLABLE, ''No'', ''DELETED COLUMN'' as Comment
    from {OLD}.INFORMATION_SCHEMA.COLUMNS oc
    where CONCAT(oc.TABLE_NAME, ''.'', oc.COLUMN_NAME) 
        not in (Select CONCAT(TABLE_NAME, ''.'', COLUMN_NAME) from {NEW}.INFORMATION_SCHEMA.COLUMNS)
';


Set @script = replace(@script, '{OLD}', @oldmodel);
Set @script = replace(@script, '{NEW}', @newmodel);

--print @script

Insert into @Temp
    exec(@script);

Select * from @Temp where Comment <> '--'
order by TABLE_NAME, ORDINAL_POSITION, COLUMN_NAME;
go
John Adams
fonte
Para uma solução rápida e suja que não requer nenhum software extra, isso é ótimo! É exatamente o que eu precisava. Obrigado!
Mir
2

Se você precisar comparar mais de um arquivo de banco de dados, poderá criar um script SQLPackage.exe.

Não tenho código de trabalho para você, mas você pode consultar a documentação do SQLPackage.exe para obter alguma inspiração.

Você extrairia seu banco de dados mestre para um arquivo dacpac e, em seguida, compararia o arquivo dacpac com o restante dos seus bancos de dados. O resultado da comparação pode ser um relatório xml das alterações ou um arquivo .sql que você pode executar para sincronizar os bancos de dados.

Algo assim:

sqlpackage.exe /a:Extract /scs:Server=MyLaptopSQL2014;Database=Test; /tf:C:UsersKevin3NFDocumentsSQLScriptsDACPACSTest.dacpac  

e depois

sqlpackage.exe /a:Script /sf:C:UsersKevin3NFDocumentsSQLScriptsDACPACSTest.dacpac /tsn:MyLaptopSQL2014 /tdn:Test1 /op:C:UsersKevin3NFDocumentsSQLScriptsDACPACSDeltasTest1.sql /p:DropObjectsNotInSource=True /p:DropIndexesNotInSource=True 
 sqlpackage.exe /a:Script /sf:C:UsersKevin3NFDocumentsSQLScriptsDACPACSTest.dacpac /tsn:MyLaptopSQL2014 /tdn:Test2 /op:C:UsersKevin3NFDocumentsSQLScriptsDACPACSDeltasTest2.sql /p:DropObjectsNotInSource=True /p:DropIndexesNotInSource=True 

Você pode dar uma olhada neste artigo ou neste para obter um código de exemplo.

Tom V - Equipe Monica
fonte
1

Faça uma pesquisa por "SQL Server Compare" e você encontrará muitas ferramentas. O que usamos no meu trabalho é o Red Gate SQLCompare . Tem um teste de 14 dias. Mas como você está falando de dois ambientes diferentes, acho que isso não funcionaria para você, a menos que o cliente envie um backup do banco de dados. A outra opção é escrever consultas nas tabelas do sistema (como sys.indexes, sys.tables, etc).

Chris Woods
fonte
A comparação do SQL funciona bem se você tiver logons nos dois servidores. Você pode usar um login diferente para cada banco de dados, para que o cliente tenha que garantir que você tenha acesso.
MarkSinkinson
1

A maneira mais fácil é usar uma ferramenta automatizada criada para esse fim , mas se você não tiver acesso a uma, poderá obter todas as informações básicas necessárias no siteINFORMATION_SCHEMA visualizações.

Usando os metadados em INFORMATION_SCHEMA provavelmente é uma opção mais fácil do que gerar scripts DDL e fazer uma comparação de origem, porque você tem muito mais controle sobre como os dados são apresentados. Você realmente não pode controlar a ordem na qual os scripts gerados apresentarão os objetos em um banco de dados. Além disso, os scripts contêm um monte de texto que pode ser dependente da implementação por padrão e pode causar muitos "ruídos" de incompatibilidade quando o que você provavelmente realmente precisa focar é uma tabela, exibição ou coluna ausente, ou possivelmente um tipo de dados de coluna ou incompatibilidade de tamanho.

Escreva uma consulta (ou consultas) para obter as informações importantes para o seu código a partir das INFORMATION_SCHEMAvisualizações e execute-a em cada SQL Server do SSMS. Você pode despejar os resultados em um arquivo e usar uma ferramenta de comparação de arquivos de texto (mesmo o MS Word) ou despejar os resultados em tabelas e executar consultas SQL para encontrar incompatibilidades.

Joel Brown
fonte
1

Estou incluindo esta resposta em prol de uma nova pergunta que foi marcada como duplicada.

Uma vez, tive que comparar dois bancos de dados de produção e encontrar diferenças de esquema entre eles. Os únicos itens de interesse eram tabelas que foram adicionadas ou eliminadas e colunas que foram adicionadas, removidas ou alteradas. Não tenho mais os scripts SQL que desenvolvi, mas o que se segue é a estratégia geral. E o banco de dados não era o SQL Server, mas acho que a mesma estratégia se aplica.

Primeiro, criei o que pode ser melhor descrito como um metadatabase. As tabelas de usuários desse banco de dados continham descrições de dados copiadas das tabelas de sistema dos bancos de dados de produção. Coisas como nome da tabela, nome da coluna, tipo de dados e precisão. Havia mais um item, Nome do banco de dados, que não existia em nenhum dos bancos de dados de produção.

Em seguida, desenvolvi scripts que acoplavam seleções das tabelas do sistema dos bancos de dados de produção com inserções nas tabelas de usuários do metadatabase.

Por fim, desenvolvi consultas para encontrar tabelas que existiam em um banco de dados, mas não no outro, e colunas de tabelas no banco de dados que estavam em apenas um banco de dados e colunas com definições inconsistentes entre os dois bancos de dados.

Das cerca de 100 tabelas e 600 colunas, encontrei algumas inconsistências e uma coluna que foi definida como um ponto flutuante em um banco de dados e um número inteiro no outro. Esse último acabou sendo uma dádiva de Deus, porque descobriu um problema que atormenta um dos bancos de dados há anos.

O modelo para o metadatabase foi sugerido pelas tabelas do sistema em questão. As consultas não foram difíceis de construir, girando principalmente em torno do grupo e tendo count (nome do banco de dados) = 1.

No seu caso, com 700 bancos de dados de produção, convém automatizar as duas primeiras etapas mais do que eu fiz com apenas dois bancos de dados para comparar. Mas a ideia é semelhante.

Walter Mitty
fonte
1

Eu tinha exatamente essa mesma pergunta e acredito que o Microsoft SQL Server Management Studio (SSMS) tem uma solução muito mais fácil / mais simples do que qualquer coisa que eu vi aqui. Eu tenho um site de produção com o MS SQL Server Express e, em breve, vários outros em que não quero instalar o VisualStudio ou outros aplicativos que não sejam o SSMS.

Portanto, no SSMS, clique com o botão direito do mouse no banco de dados para obter o esquema. Selecione Tarefas> Gerar scripts ... para abrir um assistente para criar scripts para o esquema e a configuração de todo o banco de dados (ou objetos selecionados, se desejar). Eu mantive todas as opções padrão, exceto o caminho / nome do arquivo, mas a ferramenta possui uma infinidade de opções. O assistente criou um SQL que eu copiei via OneDrive de volta para o meu PC. Em seguida, usei o Notepad ++ para comparar o SQL com um arquivo gerado da mesma maneira no meu banco de dados SIT. Você precisa filtrar os hits da data / hora nos comentários, mas, caso contrário, é uma ótima comparação dos dois bancos de dados.

Presto! Escrever isso foi significativamente mais difícil do que fazer a comparação real.

RBrown
fonte
0

Uma ótima ferramenta que eu uso (embora ainda não esteja atualizada há algum tempo ainda funciona) é o AdeptSqlDiff

O esquema e as comparações de dados são comparados. Assim como o RedGate, existe um custo, mas também um teste de 30 dias. E o preço é bastante razoável.

TombMedia
fonte
0

Talvez este script gratuito https://github.com/dlevsha/compalex possa ajudá-lo. Ele suporta o Microsoft SQL Server.

Compalex é um script leve e gratuito para comparar dois esquemas de banco de dados. Ele suporta MySQL, MS SQL Server e PostgreSQL.

Você pode experimentar a demonstração aqui

http://demo.compalex.net/

DLevsha
fonte
0

Existem muitas ferramentas de terceiros por aí que fazem comparação de esquemas e dados e sincronização. Duas ferramentas que você pode usar são as que minha equipe e eu desenvolvemos: xSQL Schema Compare para comparações de esquema e xSQL Data Compare para comparações de dados entre objetos com o mesmo esquema. Espero que isto ajude!
Isenção de responsabilidade: sou afiliado ao xSQL

Endi Zhupani
fonte
0

Existem muitas ferramentas no mercado que você pode usar para realizar o trabalho. Minha empresa está usando o ApexSQL Diff para comparação e sincronização porque é gratuito para o Azure, mas você não pode errar com as ferramentas Devart ou Redgate.

Mspaja
fonte
0

Sou fã do SQL DBDiff , que é uma ferramenta de código aberto que você pode usar para comparar tabelas, visualizações, funções, usuários etc. de duas instâncias de bancos de dados do SQL Server e gerar um script de alteração entre os bancos de dados de origem e de destino.

Shridhar
fonte
0

Eu criei um utilitário MssqlMerge que permite comparar bancos de dados MSSQL, estrutura e dados. Existe uma versão gratuita disponível que permite comparar definições de tabelas, visualizações, procedimentos e funções armazenados. E também há uma versão Pro que suporta mais tipos de objetos e possui o recurso 'Query result diff', onde você pode executar e comparar quaisquer resultados de consulta, incluindo consultas em exibições do sistema, para comparar outros detalhes não disponíveis imediatamente.

sarh
fonte
-1

Veja isso:

SELECT TABLE_SCHEMA ,
       TABLE_NAME ,
       COLUMN_NAME ,
       ORDINAL_POSITION ,
       COLUMN_DEFAULT ,
       DATA_TYPE ,
       CHARACTER_MAXIMUM_LENGTH ,
       NUMERIC_PRECISION ,
       NUMERIC_PRECISION_RADIX ,
       NUMERIC_SCALE ,
       DATETIME_PRECISION
FROM   INFORMATION_SCHEMA.COLUMNS
where TABLE_SCHEMA in ('dbo','meta')
and table_name in (select name from sys.tables)
order by TABLE_SCHEMA ,       TABLE_NAME ,ORDINAL_POSITION

insira a descrição da imagem aqui

Jeremy Thompson
fonte
3
Este realmente precisa ser sobre a comparação, não apenas recebendo o esquema
Mark Sinkinson
Vou deixar aqui, pois isso ajuda os outros. Ajudou-me #
2148 Jeremy Thompson
-1

Eu uso esta ferramenta gratuita (e de código aberto): OpenDBDiff

Tommy
fonte
-1

DBDiff é a melhor ferramenta para isso, você pode encontrá-lo aqui .

levisaligue
fonte
Bem-vindo aos administradores de banco de dados! Como você vê, todas as respostas bem recebidas aqui são mais do que apenas um link . Por favor, considere editar sua resposta e adicionar mais informações sobre o software, especialmente como ele atende aos requisitos da pergunta.
Glorfindel