Faire une table égale à une autre sans supprimer *

Je sais que c'est un peu étrange, mais si quelqu'un avait de l'aide qui serait grandement appréciée.

Le scénario est que nous avons une database de production sur un site distant et une database de développeurs dans notre bureau local. Les développeurs apportent des modifications directement au développeur db et, dans le cadre du process de deployment, une application C # s'exécute et produit une série de scripts .sql que nous pouvons exécuter du côté distant (essentiellement delete *, insert) mais nous cherchons quelque chose plus compliqué que le time d'arrêt de la suppression * est inacceptable. Ce sont toutes datatables de reference qui contrôlent les éléments de menu, la fonctionnalité, etc. d'un site Web important.

J'ai un sproc qui renvoie essentiellement une différence de deux tables. Ma pensée est que je peux insert toutes datatables attendues dans une table tmp, exécuter le diff, et laisser tomber n'importe quoi de la table de destination qui n'est pas dans la source, puis remonter tout le rest.

La question est: existe-t-il un moyen facile de le faire sans utiliser de slider? Pour illustrer le sproc renvoie un jeu d'loggings structuré comme ceci:

TableName Col1 Col2 Col3 Dest Src

Tout ce qui se trouve dans le jeu d'loggings avec TableName = Dest doit être supprimé (car il n'existe pas dans src) et tout élément dans Src doit être returnné dans dest. Je ne peux pas penser à un moyen de faire ce jeu purement basé mais mon DB-fu est faible.

Toute aide serait appréciée. Excuses si l'explication est sommaire; laissez-moi savoir si vous avez besoin de plus de détails.

Oui, ce sproc fonctionnerait. Utilisez une jointure complète avec cette table et ajoutez une colonne pour indiquer insert, mettre à jour ou supprimer. Créez ensuite des instructions SQL distinctes pour eux en fonction de l'indicateur de colonne. Définir basé.


Désolé pas une inscription complète, vous aurez besoin de les décomposer pour séparer les JOINTES GAUCHE et DROITE. Est-ce que cela a été fait dans NotePad, alors excuses si cela ne fonctionne pas:

INSERT INTO tempDeployData(ID,IUDType) SELECT ed.id, 'D' FROM tmpDeployData td RIGHT JOIN existingData ed ON td.id = ed.id WHERE td.id IS NULL UPDATE td SET td.IUDType = CASE WHEN ed.id IS NULL THEN 'I' ELSE 'U' END FROM tmpDeployData td LEFT JOIN existingData ed ON td.id = ed.id INSERT INTO existingData(ID,a,b,c) SELECT td.ID,td.a,td.b,td.c FROM tmpDeployData td WHERE td.IUDType = 'I' DELETE ed FROM existingData ed INNER JOIN tmpDeployData td ON ed.ID = td.ID WHERE td.IUDType = 'D' UPDATE ed SET ed.a = td.a, ed.b = td.b, ed.c = td.c FROM existingData ed INNER JOIN tmpDeployData td ON ed.ID = td.ID WHERE td.IUDType = 'U' 

Je viens de réaliser que vous tirez des informations dans la table des tempêtes comme une table de mise en scène, pas la source des données. Dans ce cas, vous pouvez utiliser le FULL JOIN:

 INSERT INTO tmpDeployData(ID,a,b,c,IUDType) SELECT sd.ID, sd.a, sd.b, sd.c 'IUDType' = CASE WHEN ed.id IS NULL THEN 'I' WHEN sd.id IS NULL THEN 'D' ELSE 'U' END FROM sourceData sd FULL JOIN existingData ed ON sd.id = ed.id 

Puis les mêmes instructions DML que précédemment.

Il existe un moyen beaucoup plus facile de le faire en supposant que vous utilisez SQL Server 2008: L'instruction MERGE .

La migration de tous les changements d'une table à l'autre est aussi simple que:

 MERGE DestinationTable d USING SourceTable s ON d.Id = s.Id WHEN MATCHED THEN UPDATE SET d.Col1 = s.Col1, d.Col2 = s.Col2, ... WHEN NOT MATCHED BY TARGET THEN INSERT (Id, Col1, Col2, ...) VALUES (s.Id, s.Col1, s.Col2, ...) WHEN NOT MATCHED BY SOURCE THEN DELETE; 

C'est tout. DestinationTable sera identique à SourceTable après cela.

pris au tablediff

les tables n'ont pas besoin de participer à la réplication pour exécuter l'utilitaire. il y a un merveilleux -f commutateur pour générer t-sql pour mettre les tables 'in-sync':

Génère un script Transact-SQL pour amener la table du server de destination en convergence avec la table sur le server source. Vous pouvez éventuellement spécifier un nom et un path pour le file de script Transact-SQL généré. Si le nom de file n'est pas spécifié, le file de script Transact-SQL est généré dans le directory où s'exécute l'utilitaire.

Pourquoi ne pas simplement faire une sauvegarde de la database de production et la restaurer sur votre database de développement? Vous devriez avoir des scripts de modification pour toutes les différences ddl de la database de production que vous pouvez exécuter sur la database après la restauration et tester le deployment en production.

edit: Désolé, il suffit de relire votre question, il semble que vous stockez vos informations de configuration dans votre database de développement et que vous générez vos scripts de modification à partir de cela, cela ne fonctionnera pas.

Je reorderais de créer des scripts de changement à la main et de les stocker dans le contrôle de la source. Utilisez ensuite sqlcmd ou osql et un file de commands pour exécuter vos scripts de modification sur la database.