Comment devez-vous créer votre base de données à partir du contrôle de code source?

103

Il y a eu une discussion sur le wiki de la communauté SO pour savoir si les objets de base de données doivent être contrôlés par version. Cependant, je n'ai pas vu beaucoup de discussions sur les meilleures pratiques pour créer un processus d'automatisation de construction pour les objets de base de données.

Cela a été un point de discussion controversé pour mon équipe - d'autant plus que les développeurs et les administrateurs de bases de données ont souvent des objectifs, des approches et des préoccupations différents lors de l'évaluation des avantages et des risques d'une approche d'automatisation du déploiement de bases de données.

J'aimerais entendre quelques idées de la communauté SO sur les pratiques qui ont été efficaces dans le monde réel.

Je me rends compte qu'il est quelque peu subjectif de savoir quelles pratiques sont vraiment les meilleures, mais je pense qu'un bon dialogue sur le travail pourrait être utile à de nombreuses personnes.

Voici quelques-unes de mes questions teaser sur les sujets de préoccupation de ce sujet. Celles-ci ne sont pas censées être une liste définitive - mais plutôt un point de départ pour aider les gens à comprendre ce que je recherche.

  1. Les environnements de test et de production doivent-ils être créés à partir du contrôle de code source?
    • Les deux devraient-ils être construits à l'aide de l'automatisation - ou la production devrait-elle être construite en copiant des objets à partir d'un environnement de test stable et finalisé?
    • Comment gérez-vous les différences potentielles entre les environnements de test et de production dans les scripts de déploiement?
    • Comment testez-vous que les scripts de déploiement fonctionneront aussi efficacement en production qu'en test?
  2. Quels types d'objets doivent être contrôlés par version?
    • Juste du code (procédures, packages, déclencheurs, java, etc.)?
    • Index?
    • Contraintes?
    • Définitions de table?
    • Scripts de changement de table? (par exemple, scripts ALTER)
    • Tout?
  3. Quels types d'objets ne doivent pas être contrôlés par version?
    • Des séquences?
    • Des subventions?
    • Comptes utilisateur?
  4. Comment les objets de base de données doivent-ils être organisés dans votre référentiel SCM?
    • Comment gérez-vous des choses ponctuelles comme les scripts de conversion ou les scripts ALTER?
    • Comment gérez-vous la suppression d'objets de la base de données?
    • Qui devrait être responsable de la promotion des objets du développement au niveau de test?
    • Comment coordonnez-vous les changements de plusieurs développeurs?
    • Comment gérez-vous le branchement des objets de base de données utilisés par plusieurs systèmes?
  5. Quelles exceptions, le cas échéant, peuvent être raisonnablement faites à ce processus?
    • Problèmes de sécurité?
    • Données avec des problèmes de désidentification?
    • Des scripts qui ne peuvent pas être entièrement automatisés?
  6. Comment pouvez-vous rendre le processus résilient et exécutoire?
    • À l'erreur du développeur?
    • À des problèmes environnementaux inattendus?
    • Pour la reprise après sinistre?
  7. Comment convaincre les décideurs que les avantages de DB-SCM justifient vraiment le coût?
    • Preuves anecdotiques?
    • Recherche industrielle?
    • Recommandations de bonnes pratiques de l'industrie?
    • Faire appel aux autorités reconnues?
    • L'analyse coûts-avantages?
  8. Qui devrait «posséder» les objets de base de données dans ce modèle?
    • Développeurs?
    • DBA?
    • Analystes de données?
    • Plus d'un?
LBushkin
la source
3
La profondeur de cette question demande une prime.
Greg D

Réponses:

53

Voici quelques réponses à vos questions:

  1. Les environnements de test et de production doivent-ils être créés à partir du contrôle de code source? OUI
    • Les deux devraient-ils être construits à l'aide de l'automatisation - ou la production devrait-elle être construite en copiant des objets à partir d'un environnement de test stable et finalisé?
    • L'automatisation pour les deux. Ne copiez PAS de données entre les environnements
    • Comment gérez-vous les différences potentielles entre les environnements de test et de production dans les scripts de déploiement?
    • Utilisez des modèles, de sorte que vous produisiez en fait un ensemble différent de scripts pour chaque environnement (ex. Références à des systèmes externes, bases de données liées, etc.)
    • Comment testez-vous que les scripts de déploiement fonctionneront aussi efficacement en production qu'en test?
    • Vous les testez sur un environnement de pré-production: testez le déploiement sur une copie exacte de l'environnement de production (base de données et potentiellement d'autres systèmes)
  2. Quels types d'objets doivent être contrôlés par version?
    • Juste du code (procédures, packages, déclencheurs, java, etc.)?
    • Index?
    • Contraintes?
    • Définitions de table?
    • Scripts de changement de table? (par exemple, scripts ALTER)
    • Tout?
    • Tout, et:
      • N'oubliez pas les données statiques (listes de recherche, etc.), vous n'avez donc pas besoin de copier AUCUNE donnée entre les environnements
      • Conserver uniquement la version actuelle des scripts de base de données (contrôle de version, bien sûr), et
      • Stockez les scripts ALTER: 1 BIG script (ou répertoire de scripts nommé comme aimé 001_AlterXXX.sql, de sorte que leur exécution dans l'ordre de tri naturel passe de la version A à B)
  3. Quels types d'objets ne doivent pas être contrôlés par version?
    • Des séquences?
    • Des subventions?
    • Comptes utilisateur?
    • voir 2. Si vos utilisateurs / rôles (ou noms d'utilisateurs techniques) sont différents entre les environnements, vous pouvez toujours les écrire à l'aide de modèles (voir 1.)
  4. Comment les objets de base de données doivent-ils être organisés dans votre référentiel SCM?
    • Comment gérez-vous des choses ponctuelles comme les scripts de conversion ou les scripts ALTER?
    • voir 2.
    • Comment gérez-vous la suppression d'objets de la base de données?
    • supprimé de la base de données, supprimé du tronc / de la pointe de contrôle de source
    • Qui devrait être responsable de la promotion des objets du développement au niveau de test?
    • calendrier de développement / test / publication
    • Comment coordonnez-vous les changements de plusieurs développeurs?
    • essayez de ne PAS créer une base de données distincte pour chaque développeur. vous utilisez le contrôle de source, non? dans ce cas, les développeurs modifient la base de données et enregistrent les scripts. pour être complètement sûr, recréez la base de données à partir des scripts pendant la construction nocturne
    • Comment gérez-vous le branchement des objets de base de données utilisés par plusieurs systèmes?
    • difficile: essayez d'éviter à tout prix.
  5. Quelles exceptions, le cas échéant, peuvent être raisonnablement faites à ce processus?
    • Problèmes de sécurité?
    • ne stockez pas les mots de passe pour test / prod. vous pouvez l'autoriser pour les développeurs, surtout si vous avez des reconstructions de base de données automatisées quotidiennes / nocturnes
    • Données avec des problèmes de désidentification?
    • Des scripts qui ne peuvent pas être entièrement automatisés?
    • documenter et stocker avec le script release info / ALTER
  6. Comment pouvez-vous rendre le processus résilient et exécutoire?
    • À l'erreur du développeur?
    • testé avec une construction quotidienne à partir de zéro, et comparez les résultats à la mise à niveau incrémentielle (de la version A à B en utilisant ALTER). comparer à la fois le schéma résultant et les données statiques
    • À des problèmes environnementaux inattendus?
    • utiliser le contrôle de version et les sauvegardes
    • comparez le schéma de la base de données PROD à ce que vous pensez qu'il est, en particulier avant le déploiement. SuperDuperCool DBA a peut-être corrigé un bogue qui n'était jamais dans votre système de tickets :)
    • Pour la reprise après sinistre?
  7. Comment convaincre les décideurs que les avantages de DB-SCM justifient vraiment le coût?
    • Preuves anecdotiques?
    • Recherche industrielle?
    • Recommandations de bonnes pratiques de l'industrie?
    • Faire appel aux autorités reconnues?
    • L'analyse coûts-avantages?
    • si les développeurs et les DBA sont d'accord, vous n'avez pas besoin de convaincre qui que ce soit, je pense (sauf si vous avez besoin d'argent pour acheter un logiciel comme un dbGhost pour MSSQL)
  8. Qui devrait «posséder» les objets de base de données dans ce modèle?
    • Développeurs?
    • DBA?
    • Analystes de données?
    • Plus d'un?
    • Habituellement, les administrateurs de base de données approuvent le modèle (avant l'enregistrement ou après dans le cadre de la révision du code). Ils possèdent définitivement des objets liés aux performances. Mais en général, l'équipe en est propriétaire [et l'employeur, bien sûr :)]
van
la source
Merci pour votre réponse! Pensez-vous que ces recommandations s'appliquent à tous les projets? Connaissez-vous des outils qui permettent d'atteindre ce niveau d'automatisation? Je mettrai à jour ma question à mesure que de plus en plus de personnes y pèseront. De plus, sachez que mes questions «teaser» n'étaient pas censées être une liste définitive de préoccupations à aborder - mais plutôt un point de départ pour la discussion.
LBushkin
Clair. Je pense que vous avez soulevé une très très bonne question. Et j'espère vraiment que la question suscitera suffisamment d'intérêt pour que vous puissiez compiler un excellent wiki HowTo sur le sujet. ---- des outils: j'ai utilisé dbGhost d'Innovartis, que j'ai mentionné dans les réponses pour la gestion du serveur MSSQL et cela a fait un excellent travail. Il existe probablement d'autres outils pour le travail, mais étant donné que le schéma SQL complet n'est pas vraiment standard chez les fournisseurs, il n'y a pas de solution tout-en-un (pour tous les SCM et RDMBS).
van
Bonne réponse. Je suppose que "rechercher des listes" signifie les données qui sont utilisées pour remplir les cases <select>? Cela n'est peut-être pas toujours possible, car ces données peuvent être modifiées par les utilisateurs (d'une certaine manière) en production. Garder des sauvegardes a du sens dans ce cas. Vous suggérez également de recréer la base de données à partir de zéro dans le cadre d'une génération nocturne. Je ne pense pas que ce soit une bonne idée; il peut supprimer des travaux en cours ou nécessiter une réinstallation / configuration d'autres logiciels. Enfin, je suggérerais de créer des modes de test, des validateurs de données et d'autres outils au lieu de créer à partir de zéro pour garantir des processus résilients.
Richard Levasseur
@Richard. Bons points, mais quand même. Lorsque vous lisez «créer une base de données à partir de zéro», cela ne signifie pas toujours supprimer les données. Il s'agit de reconstruire le schéma et les données statiques. S'il y a un travail en cours (concernant le schéma ou les données statiques), il devrait être dans le contrôle de code source, donc il fera partie de la construction nocturne. Si vous travaillez sur la branche avec une refonte majeure de la base de données, vous disposez d'une base de données distincte pour ce type de développement. Et si vous utilisez des tests unitaires, vous ne vous fiez pas à l'état des données dans la base de données, mais créez / supprimez dans le cadre de db-unit-test. --- Données statiques consommables par les utilisateurs - d'accord.
van
Je ne suis pas d'accord avec la reconstruction des bases de données tous les soirs. Alors que tout ce qui définit la base de données, comme les schémas, les déclencheurs, les procédures stockées et certaines données statiques «gérées» doit être scripté, le matériel réel ne doit pas l'être. Le contenu lui-même peut être piloté par les tâches du développeur. Nous avons des développeurs qui travaillent sur des ensembles de données à des fins de test et d'expérimentation. Et s'ils arrivaient chaque jour et que leur état actuel était "réinitialisé"? Pas bon. J'utilise des tests TestNG qui effacent certaines tables, puis préchargent avec des données de test chaque jour. Cela ne ressemble pas à un candidat au contrôle de source.
gregturn
5

Je traite le SQL comme un code source lorsque cela est possible

Si je peux l'écrire dans le SQL conforme à la norme, il va généralement dans un fichier de mon contrôle de source. Le fichier définira autant que possible comme les SP, les instructions Table CREATE.

J'inclus également des données factices pour les tests dans le contrôle de code source:

  1. proj / sql / setup_db.sql
  2. proj / sql / dummy_data.sql
  3. proj / sql / mssql_specific.sql
  4. proj / sql / mysql_specific.sql

Et puis je résume toutes mes requêtes SQL afin de pouvoir construire l'ensemble du projet pour MySQL, Oracle, MSSQL ou autre.

L'automatisation de la construction et des tests utilise ces scripts de construction car ils sont aussi importants que la source de l'application et teste tout, de l'intégrité aux déclencheurs, aux procédures et à la journalisation.

Aiden Bell
la source
4

Nous utilisons l'intégration continue via TeamCity. À chaque enregistrement dans le contrôle de code source, la base de données et toutes les données de test sont reconstruites à partir de zéro, puis le code, puis les tests unitaires sont exécutés par rapport au code. Si vous utilisez un outil de génération de code tel que CodeSmith, il peut également être placé dans votre processus de construction pour générer votre couche d'accès aux données à chaque construction, en vous assurant que toutes vos couches «correspondent» et ne produisent pas d'erreurs dues à paramètres SP incompatibles ou colonnes manquantes.

Chaque build possède sa propre collection de scripts SQL qui sont stockés dans le répertoire $ project \ SQL \ du contrôle de code source, affectés d'un préfixe numérique et exécutés dans l'ordre. De cette façon, nous pratiquons notre procédure de déploiement à chaque build.

En fonction de la table de recherche, la plupart de nos valeurs de recherche sont également stockées dans des scripts et exécutées pour s'assurer que les données de configuration correspondent à ce que nous attendons, par exemple "reason_codes" ou "country_codes". De cette façon, nous pouvons modifier les données de recherche dans le développement, les tester, puis les «promouvoir» via le contrôle qualité et la production, au lieu d'utiliser un outil pour modifier les valeurs de recherche en production, ce qui peut être dangereux pour la disponibilité.

Nous créons également un ensemble de scripts "rollback" qui annulent les modifications de notre base de données, au cas où une construction en production deviendrait fausse. Vous pouvez tester les scripts de restauration en les exécutant, puis en réexécutant les tests unitaires pour la version build one inférieure à la vôtre, après l'exécution de ses scripts de déploiement.

Chris McCall
la source
4

+1 pour Liquibase : LiquiBase est une bibliothèque open source (LGPL) indépendante de la base de données pour le suivi, la gestion et l'application des modifications de base de données. Il est construit sur une prémisse simple: toutes les modifications de la base de données (structure et données) sont stockées de manière descriptive XML et archivées dans le contrôle de code source. Le bon point, que les modifications DML sont stockées sémantiquement, pas seulement diff, afin que vous puissiez suivre l'objectif des modifications.

Il pourrait être combiné avec le contrôle de version GIT pour une meilleure interaction. Je vais configurer notre environnement dev-prod pour l'essayer.

Vous pouvez également utiliser Maven, les systèmes de construction Ant pour créer du code de production à partir de scripts.

Le moins est que LiquiBase ne s'intègre pas dans les IDE SQL répandus et que vous devez effectuer vous-même les opérations de base.

En plus de cela, vous pouvez utiliser DBUnit pour les tests DB - cet outil permet d'utiliser des scripts de génération de données pour tester votre environnement de production avec un nettoyage ultérieur.

A MON HUMBLE AVIS:

  1. Stockez le DML dans des fichiers afin de pouvoir les versions.
  2. Automatisez le processus de création de schéma à partir du contrôle de code source.
  3. À des fins de test, le développeur peut utiliser la base de données locale créée à partir du contrôle de code source via le système de génération + les données de test de charge avec des scripts ou des scripts DBUnit (à partir du contrôle de code source).
  4. LiquiBase vous permet de fournir une «séquence d'exécution» de scripts pour respecter les dépendances.
  5. Il devrait y avoir une équipe DBA qui vérifie le brunch principal avec TOUS les changements avant l'utilisation en production. Je veux dire qu'ils vérifient le tronc / branche des autres DBA avant de s'engager dans le tronc MASTER. Pour que le maître soit toujours cohérent et prêt pour la production.

Nous avons fait face à tous les problèmes mentionnés avec les changements de code, la fusion, la réécriture dans notre base de données de production de facturation. Ce sujet est idéal pour découvrir tout cela.

zmische
la source
3

En posant des "questions teaser", vous semblez être plus intéressé par une discussion que l'opinion de quelqu'un sur les réponses finales. La liste de diffusion active (> 2500 membres) agileDatabases a répondu à bon nombre de ces questions et constitue, d'après mon expérience, un forum sophistiqué et civil pour ce type de discussion.

Glenn
la source
Je pense qu'il est peu probable qu'une réponse unique et universellement acceptée puisse être trouvée. Mais je voudrais identifier quelques domaines d’accord communs - et peut-être élaborer une recommandation raisonnable. Je vais certainement regarder le forum agileDatabases aussi, merci.
LBushkin
3

Je suis fondamentalement d'accord avec chaque réponse donnée par van . Pour plus de perspicacité, ma base de référence pour la gestion de base de données est la série K. Scott Allen (une lecture incontournable , à mon humble avis. Et l'opinion de Jeff aussi semble-t-il).

  • Objets de base de données peuvent toujours être reconstruits à partir de zéro en lançant un seul fichier SQL (qui peut s'appeler d' autres fichiers SQL): Create.sql. Cela peut inclure l' insertion de données statiques (listes ...).
  • Les scripts SQL sont paramétrés de sorte qu'aucune information dépendante de l'environnement et / ou sensible ne soit stockée dans des fichiers simples.
  • J'utilise un fichier batch personnalisé pour le lancement Create.sql: Create.cmd. Son objectif est principalement de vérifier les pré-requis (outils, variables d'environnement ...) et d'envoyer des paramètres au script SQL. Il peut également charger en masse des données statiques à partir de fichiers CSV pour des problèmes de performances.
  • En règle générale, les informations d'identification de l'utilisateur système sont transmises en tant que paramètre au Create.cmdfichier.

À mon humble avis, le chargement dynamique des données devrait nécessiter une autre étape, en fonction de votre environnement. Les développeurs voudront charger leur base de données avec des données de test, des fichiers indésirables ou aucune donnée, tandis qu'à l'autre extrémité, les responsables de la production voudront charger les données de production. J'envisagerais également de stocker les données de test dans le contrôle de source (pour faciliter les tests unitaires, par exemple).

Une fois la première version de la base de données mise en production, vous aurez besoin non seulement de scripts de construction (principalement pour les développeurs), mais également de scripts de mise à niveau (basés sur les mêmes principes):

  • Il doit y avoir un moyen de récupérer la version de la base de données (j'utilise une procédure stockée, mais une table ferait aussi bien).
  • Avant de publier une nouvelle version, je crée un Upgrade.sqlfichier (qui peut en appeler d'autres) qui permet de mettre à niveau la version N-1 vers la version N (N étant la version en cours de publication). Je stocke ce script dans un dossier nommé N-1.
  • J'ai un fichier batch qui fait la mise à niveau: Upgrade.cmd. Il peut récupérer la version actuelle (CV) de la base de données via une simple instruction SELECT, lancer le Upgrade.sqlscript stocké sous le CVdossier et effectuer une boucle jusqu'à ce qu'aucun dossier ne soit trouvé. De cette façon, vous pouvez automatiquement passer de, disons, N-3 à N.

Les problèmes avec ceci sont:

  • Il est difficile de comparer automatiquement les schémas de base de données, selon les fournisseurs de bases de données. Cela peut conduire à des scripts de mise à niveau incomplets.
  • Chaque modification apportée à l'environnement de production (généralement par les administrateurs de base de données pour le réglage des performances) doit également trouver son chemin vers le contrôle de code source. Pour s'en assurer, il est généralement possible d'enregistrer chaque modification dans la base de données via un déclencheur. Ce journal est réinitialisé après chaque mise à niveau.
  • Plus idéalement, cependant, les modifications initiées par DBA devraient faire partie du processus de publication / mise à niveau lorsque cela est possible.

Quant à quel type d'objets de base de données voulez-vous avoir sous contrôle de code source? Eh bien, je dirais autant que possible, mais pas plus ;-) Si vous voulez créer des utilisateurs avec des mots de passe, obtenez-leur un mot de passe par défaut (login / login, pratique pour les tests unitaires), et faites du changement de mot de passe une opération manuelle . Cela se produit souvent avec Oracle où les schémas sont également des utilisateurs ...

Mac
la source
1

Nous avons notre projet Silverlight avec la base de données MSSQL dans le contrôle de version Git. Le moyen le plus simple est de vous assurer que vous avez une base de données allégée (en termes de contenu) et de faire un vidage complet à partir de Visual Studio. Ensuite, vous pouvez faire 'sqlcmd' à partir de votre script de construction pour recréer la base de données sur chaque machine de développement.

Pour le déploiement, cela n'est pas possible car les bases de données sont trop volumineuses: c'est la raison principale pour les avoir dans une base de données en premier lieu.

Rutger Nijlunsing
la source
1

Je crois fermement qu'une base de données doit faire partie du contrôle de code source et, dans une large mesure, du processus de construction. S'il s'agit du contrôle de code source, j'ai les mêmes protections de codage lors de l'écriture d'une procédure stockée en SQL que lors de l'écriture d'une classe en C #. Je fais cela en incluant un répertoire de scripts DB sous mon arborescence source. Ce répertoire de script n'a pas nécessairement un fichier pour un objet dans la base de données. Ce serait une douleur dans le cul! Je développe dans ma base de données juste comme je le ferais dans mon projet de code. Ensuite, lorsque je suis prêt à m'enregistrer, je fais une différence entre la dernière version de ma base de données et celle sur laquelle je travaille. J'utilise SQL Compare pour cela et il génère un script de toutes les modifications. Ce script est ensuite enregistré dans mon répertoire db_update avec une convention de dénomination spécifique 1234_TasksCompletedInThisIteration où le numéro est le numéro suivant dans l'ensemble de scripts déjà présents, et le nom décrit ce qui est fait lors de cet archivage. Je fais de cette façon car comme une partie de mon processus de construction, je commence avec une nouvelle base de données qui est ensuite construite par programme en utilisant les scripts de ce répertoire. J'ai écrit une tâche NAnt personnalisée qui itère à travers chaque script en exécutant son contenu sur la base de données nue. Évidemment, si j'ai besoin de certaines données pour entrer dans la base de données, j'ai également des scripts d'insertion de données. Cela présente également de nombreux avantages. Premièrement, toutes mes affaires sont versionnées. Deuxièmement, chaque version est une nouvelle version, ce qui signifie qu'il n'y aura pas de trucs sournois dans mon processus de développement (comme des données sales qui causent des bizarreries dans le système). Troisièmement, lorsqu'un nouveau membre est ajouté à l'équipe de développement, il doit simplement être informé des dernières mises à jour et son développeur local est conçu pour lui à la volée. Quatre, je peux exécuter des cas de test (je ne l'ai pas appelé un «test unitaire»!) Sur ma base de données car l'état de la base de données est réinitialisé à chaque build (ce qui signifie que je peux tester mes référentiels sans me soucier d'ajouter des données de test au db).

Ce n'est pas pour tout le monde.

Ce n'est pas pour tous les projets. Je travaille généralement sur des projets de champs verts ce qui me permet cette commodité!

Andrew Siemer
la source
Heureux d'apprendre que vous utilisez SQL Compare dans le cadre du cycle de vie de développement de votre base de données. Nous pensons que nous avons peut-être amélioré la facilité des développeurs à obtenir de nouveaux changements. Découvrez le contrôle de source SQL. Cela fonctionne côte à côte avec SQL Compare pour faciliter la collaboration des développeurs et vous permettre de garder vos objets de schéma sous contrôle source (à condition que vous utilisiez SVN ou TFS). red-gate.com/products/sql_source_control/index.htm
David Atkinson
1

Plutôt que d'entrer dans les arguments de la tour blanche, voici une solution qui a très bien fonctionné pour moi sur les problèmes du monde réel.

Construire une base de données à partir de zéro peut se résumer à la gestion de scripts SQL.

DBdeploy est un outil qui vérifie l'état actuel d'une base de données - par exemple, quels scripts ont été précédemment exécutés sur elle, quels scripts sont disponibles pour être exécutés et par conséquent quels scripts doivent être exécutés.

Il rassemblera ensuite tous les scripts nécessaires et les exécutera. Il enregistre ensuite les scripts exécutés.

Ce n'est pas l'outil le plus joli ni le plus complexe, mais avec une gestion minutieuse, il peut très bien fonctionner. C'est open source et facilement extensible. Une fois que l'exécution des scripts est bien gérée, il est facile d'ajouter des composants supplémentaires tels qu'un script shell qui extrait les derniers scripts et exécute dbdeploy sur une instance particulière.

Voir une bonne introduction ici:

http://code.google.com/p/dbdeploy/wiki/GettingStarted

Pablojim
la source
0

Vous constaterez peut-être que Liquibase gère une grande partie de ce que vous recherchez.

David Plumpton
la source
0

Chaque développeur doit avoir sa propre base de données locale et utiliser le contrôle du code source pour publier dans l'équipe. Ma solution est ici: http://dbsourcetools.codeplex.com/ Amusez-vous bien, - Nathan

Nathan Rozentals
la source