Comment comparer le schéma de deux bases de données?


19

Existe-t-il un moyen de trouver les différences dans deux bases de données SQL Server (schéma uniquement). L'un est local et le second est sur le site d'un client. Nous rencontrons des problèmes avec les rapports Crystal exécutant certains rapports et certains codes ne s'exécutant pas et il semblerait que les schémas ne correspondent pas.

Puis-je exécuter la même commande sur les deux bases de données et comparer les résultats pour savoir où se trouvent les différences?


Cette question sur SO a quelques bonnes suggestions.
LowlyDBA

Réponses:


13

Si vous ne pouvez pas utiliser l'un des nombreux outils disponibles en raison de problèmes de connectivité et souhaitez une comparaison "hors ligne", vous pouvez utiliser SSMS pour générer des scripts pour tous les objets de base de données en cliquant avec le bouton droit sur la base de données et en utilisant la commande "Tâches ... / Générer". Scripts "et assurez-vous de choisir de créer un fichier par objet.

Lorsque vous avez fait cela pour les deux bases de données, placez les deux ensembles de scripts sur une machine locale dans deux dossiers distincts et utilisez WinMerge (ou similaire) pour comparer les deux.


6

Une autre option consiste à utiliser SQL Server Data Tools (SSDT), une extension de Visual Studio. Vous pouvez extraire votre schéma de base de données sous forme de fichier .dacpac et le comparer avec un autre fichier .dacpac ou une base de données existante. SSDT est inclus avec les outils clients SQL Server 2012, ce qui le rend assez accessible. Vous pouvez trouver les instructions complètes sur la façon d'exécuter la comparaison sur le site MSDN .


6

Après avoir lutté avec un moyen facile de faire cette même tâche - voir ce qui a changé entre 2 modèles, j'ai écrit le script SQL suivant qui comparera deux schémas pour déterminer les colonnes nouvelles et supprimées

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

Pour une solution rapide et sale qui ne nécessite aucun logiciel supplémentaire, c'est parfait! C'est exactement ce dont j'avais besoin. Merci!
Mir

2

Si vous devez comparer plusieurs fichiers de base de données, vous pouvez créer un script SQLPackage.exe.

Je n'ai pas de code de travail pour vous, mais vous pouvez consulter la documentation SQLPackage.exe pour vous inspirer.

Vous devez extraire votre base de données principale dans un fichier dacpac, puis comparer le fichier dacpac au reste de vos bases de données. Le résultat de la comparaison peut être un rapport xml des modifications ou un fichier .sql que vous pouvez exécuter pour synchroniser les bases de données.

Quelque chose comme ça:

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

puis

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 

Vous pouvez consulter cet article ou celui-ci pour un exemple de code.


1

Effectuez une recherche pour «SQL Server Compare» et vous trouverez de nombreux outils. Celui que nous utilisons dans mon travail est Red Gate SQLCompare . Il a un procès de 14 jours. Mais comme vous parlez de deux environnements différents, je ne pense pas que cela fonctionnerait pour vous, à moins que le client ne vous envoie une sauvegarde de leur base de données. L'autre option consiste à écrire des requêtes sur les tables système (comme sys.indexes, sys.tables, etc.).


La comparaison SQL fonctionne correctement si vous vous connectez aux deux serveurs. Vous pouvez utiliser une connexion différente à chaque base de données, de sorte que le client doit s'assurer que vous y avez accès.
Mark Sinkinson

1

Le moyen le plus simple consiste à utiliser un outil automatisé conçu à cet effet , mais si vous n'y avez pas accès, vous pouvez obtenir toutes les informations de base dont vous avez besoin à partir des INFORMATION_SCHEMAvues.

L'utilisation des métadonnées dans INFORMATION_SCHEMAest probablement une option plus facile que la génération de scripts DDL et la comparaison de sources car vous avez beaucoup plus de contrôle sur la façon dont les données sont présentées. Vous ne pouvez pas vraiment contrôler l'ordre dans lequel les scripts générés présenteront les objets dans une base de données. De plus, les scripts contiennent un tas de texte qui peut être dépendant de l'implémentation par défaut et peut causer beaucoup de "bruit" de discordance lorsque vous devez probablement vous concentrer sur une table, une vue ou une colonne manquante, ou éventuellement un type de données de colonne ou la différence de taille.

Écrivez une ou plusieurs requêtes pour obtenir les informations importantes pour votre code à partir des INFORMATION_SCHEMAvues et exécutez-les sur chaque serveur SQL à partir de SSMS. Vous pouvez ensuite soit vider les résultats dans un fichier et utiliser un outil de comparaison de fichiers texte (même MS Word), soit vider les résultats dans des tableaux et exécuter des requêtes SQL pour trouver des incompatibilités.


1

J'inclus cette réponse pour le bien d'une nouvelle question qui a été marquée comme doublon.

Une fois, j'ai dû comparer deux bases de données de production et trouver des différences de schéma entre elles. Les seuls éléments intéressants étaient les tableaux qui avaient été ajoutés ou supprimés et les colonnes qui avaient été ajoutées, supprimées ou modifiées. Je n'ai plus les scripts SQL que j'ai développés, mais ce qui suit est la stratégie générale. Et la base de données n'était pas SQL Server, mais je pense que la même stratégie s'applique.

Tout d'abord, j'ai créé ce qui peut être décrit comme une métadatabase. Les tables utilisateur de cette base de données contenaient des descriptions de données copiées à partir des tables système des bases de données de production. Des choses comme le nom de la table, le nom de la colonne, le type de données et la précision. Il y avait un autre élément, Nom de la base de données, qui n'existait dans aucune des bases de données de production.

Ensuite, j'ai développé des scripts qui couplaient les sélections des tables système des bases de données de production avec des insertions dans les tables utilisateur de la métadatabase.

Enfin, j'ai développé des requêtes pour trouver des tables qui existaient dans une base de données mais pas dans l'autre, et des colonnes de tables des deux bases de données qui n'étaient que dans une seule base de données, et des colonnes avec des définitions incohérentes entre les deux bases de données.

Sur environ 100 tables et 600 colonnes, j'ai trouvé une poignée d'incohérences et une colonne qui était définie comme un point flottant dans une base de données et un entier dans l'autre. Cette dernière s'est avérée être une aubaine, car elle a mis au jour un problème qui sévissait dans l'une des bases de données depuis des années.

Le modèle de la métadatabase a été suggéré par les tables système en question. Les requêtes n'étaient pas difficiles à construire, tournant principalement autour du groupe par et ayant count (nom de la base de données) = 1.

Dans votre cas, avec 700 bases de données de production, vous voudrez peut-être automatiser les deux premières étapes de plus que moi avec seulement deux bases de données à comparer. Mais l'idée est similaire.


1

J'avais exactement la même question et je crois que Microsoft SQL Server Management Studio (SSMS) a une solution beaucoup plus facile / simple que tout ce que j'ai vu ici. J'ai un site de production avec MS SQL Server Express et bientôt plusieurs autres où je ne veux pas avoir à installer VisualStudio ou d'autres applications autres que SSMS.

Donc, dans SSMS, faites un clic droit sur la base de données pour obtenir le schéma. Sélectionnez Tâches> Générer des scripts ... pour ouvrir un assistant de script du schéma et de la configuration pour la base de données entière (ou les objets sélectionnés si vous le souhaitez). J'ai conservé toutes les options par défaut sauf le chemin / nom de fichier, mais l'outil a une pléthore d'options. L'assistant a créé un SQL que j'ai copié via OneDrive sur mon PC. J'ai ensuite utilisé Notepad ++ pour comparer le SQL à un fichier généré de la même manière avec ma base de données SIT. Vous devez filtrer les hits de la date / heure dans les commentaires, mais sinon c'est une grande comparaison des deux bases de données.

Presto! Il a été beaucoup plus difficile de rédiger cela que de faire la comparaison réelle.


0

Un excellent outil que j'utilise (bien qu'il ne soit pas mis à jour depuis un certain temps fonctionne toujours) est AdeptSqlDiff

Est-ce que le schéma compare et compare les données. Tout comme RedGate, il y a un coût mais aussi un essai de 30 jours. Et le prix est assez raisonnable.



0

Il existe de nombreux outils tiers qui compareront les schémas et les données, ainsi que la synchronisation. Deux outils que vous pouvez utiliser sont ceux que mon équipe et moi avons développés, xSQL Schema Compare pour les comparaisons de schémas et xSQL Data Compare pour les comparaisons de données entre les objets avec le même schéma. J'espère que cela t'aides!
Avertissement: je suis affilié à xSQL


0

Il existe de nombreux outils sur le marché que vous pourriez utiliser pour faire le travail. Mon entreprise utilise ApexSQL Diff pour la comparaison et la synchronisation car elle est gratuite pour Azure, mais vous ne pouvez pas vous tromper avec les outils Devart ou Redgate.


0

Je suis un fan de SQL DBDiff , qui est un outil open source que vous pouvez utiliser pour comparer des tables, des vues, des fonctions, des utilisateurs, etc. de deux instances de bases de données SQL Server et générer un script de changement entre les bases de données source et de destination.


0

J'ai créé un utilitaire MssqlMerge qui permet de comparer les bases de données MSSQL, à la fois la structure et les données. Il existe une version gratuite qui permet de comparer les définitions de table, les vues, les procédures stockées et les fonctions. Et il existe également une version Pro qui prend en charge plus de types d'objets et dispose de la fonction `` Différence de résultat de requête '' où vous pouvez exécuter et comparer tous les résultats de requête, y compris les requêtes par rapport aux vues du système, pour comparer d'autres détails non disponibles.


-1

Regarde ça:

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

entrez la description de l'image ici


3
Il faut vraiment comparer, pas seulement obtenir le schéma
Mark Sinkinson

Je vais le laisser ici, car il aide les autres. Cela m'a aidé
Jeremy Thompson


-1

DBDiff est le meilleur outil pour cela, vous pouvez le trouver ici .


Bienvenue aux administrateurs de bases de données! Comme vous le voyez, toutes les réponses bien reçues ici sont plus qu'un simple lien . Veuillez envisager de modifier votre réponse et d'ajouter plus d'informations sur le logiciel, en particulier sur la façon dont il répond aux exigences de la question.
Glorfindel
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.