web-dev-qa-db-fra.com

Utilisez-vous le contrôle de source pour vos éléments de base de données?

Je pense que ma boutique a un trou car nous n’avons pas mis en place de processus solide pour la gestion des versions de nos modifications de schéma de base de données. Nous faisons beaucoup de sauvegardes, donc nous sommes plus ou moins couverts, mais c'est une mauvaise pratique de s'appuyer sur votre dernière ligne de défense de cette façon.

Étonnamment, cela semble être un fil conducteur. Beaucoup de magasins avec lesquels j'ai parlé ignorent ce problème parce que leurs bases de données ne changent pas souvent et essaient simplement d'être méticuleux.

Cependant, je sais comment cette histoire se passe. Ce n'est qu'une question de temps avant que les choses ne se produisent et que quelque chose manque.

Existe-t-il des meilleures pratiques pour cela? Quelles sont les stratégies qui ont fonctionné pour vous?

589
Brian MacKay

Doit lire Obtenez votre base de données sous contrôle de version . Vérifiez la série de messages de K. Scott Allen.

En matière de contrôle de version, la base de données est souvent un citoyen de deuxième, voire de troisième classe. D'après ce que j'ai vu, des équipes qui n'auraient jamais pensé à écrire du code sans contrôle de version en un million d'années - et à juste titre - peuvent oublier complètement la nécessité d'un contrôle de version autour des bases de données critiques sur lesquelles reposent leurs applications. Je ne sais pas comment vous pouvez vous appeler un ingénieur en logiciel et garder la tête froide lorsque votre base de données n'est pas sous le même niveau rigoureux de contrôle de la source que le reste de votre code. Ne laissez pas cela vous arriver. Obtenez votre base de données sous contrôle de version.

382
Gulzar Nazim

Les bases de données elles-mêmes? Non

Les scripts qui les créent, y compris les insertions de données statiques, les procédures stockées, etc. bien sûr. Ce sont des fichiers texte, ils sont inclus dans le projet et sont archivés comme tout le reste.

Bien sûr, dans un monde idéal, votre outil de gestion de base de données ferait cela; mais vous devez juste être discipliné à ce sujet.

133
blowdart

J'adore les Rails migrations ActiveRecord. Il résume le DML dans le script Ruby, qui peut ensuite être facilement mis en version dans votre référentiel source.

Cependant, avec un peu de travail, vous pourriez faire la même chose. Toutes les modifications DDL (ALTER TABLE, etc.) peuvent être stockées dans des fichiers texte. Conservez un système de numérotation (ou un horodatage) pour les noms de fichiers et appliquez-les en séquence.

Rails a également une table 'version' dans la base de données qui garde la trace de la dernière migration appliquée. Vous pouvez faire la même chose facilement.

36
Matt Rogish

Consultez LiquiBase pour gérer les modifications de la base de données à l'aide du contrôle de source.

33
killdash10

Vous ne devez jamais vous connecter et commencer à entrer des commandes "ALTER TABLE" pour modifier une base de données de production. Le projet sur lequel je travaille a une base de données sur chaque site client. Ainsi, chaque modification de la base de données est effectuée à deux endroits: un fichier de vidage utilisé pour créer une nouvelle base de données sur un nouveau site client et un fichier de mise à jour exécuté. à chaque mise à jour qui compare le numéro de version actuel de votre base de données au numéro le plus élevé du fichier et met à jour votre base de données sur place. Ainsi, par exemple, les deux dernières mises à jour:

if [ $VERSION \< '8.0.108' ] ; then
  psql -U cosuser $dbName << EOF8.0.108
    BEGIN TRANSACTION;
    --
    -- Remove foreign key that shouldn't have been there.
    -- PCR:35665
    --
    ALTER TABLE     migratorjobitems
    DROP CONSTRAINT migratorjobitems_destcmaid_fkey;
    -- 
    -- Increment the version
    UPDATE          sys_info
    SET             value = '8.0.108'
    WHERE           key = 'DB VERSION';
    END TRANSACTION;
EOF8.0.108
fi

if [ $VERSION \< '8.0.109' ] ; then
  psql -U cosuser $dbName << EOF8.0.109
    BEGIN TRANSACTION;
    --
    -- I missed a couple of cases when I changed the legacy playlist
    -- from reporting showplaylistidnum to playlistidnum
    --
    ALTER TABLE     featureidrequestkdcs
    DROP CONSTRAINT featureidrequestkdcs_cosfeatureid_fkey;
    ALTER TABLE     featureidrequestkdcs
    ADD CONSTRAINT  featureidrequestkdcs_cosfeatureid_fkey
    FOREIGN KEY     (cosfeatureid)
    REFERENCES      playlist(playlistidnum)
    ON DELETE       CASCADE;
    --
    ALTER TABLE     ticket_system_ids
    DROP CONSTRAINT ticket_system_ids_showplaylistidnum_fkey;
    ALTER TABLE     ticket_system_ids
    RENAME          showplaylistidnum
    TO              playlistidnum;
    ALTER TABLE     ticket_system_ids
    ADD CONSTRAINT  ticket_system_ids_playlistidnum_fkey
    FOREIGN KEY     (playlistidnum)
    REFERENCES      playlist(playlistidnum)
    ON DELETE       CASCADE;
    -- 
    -- Increment the version
    UPDATE          sys_info
    SET             value = '8.0.109'
    WHERE           key = 'DB VERSION';
    END TRANSACTION;
EOF8.0.109
fi

Je suis sûr qu'il existe un meilleur moyen de le faire, mais cela a fonctionné pour moi jusqu'à présent.

29
Paul Tomblin

Oui. Le code est le code. Ma règle générale est que je dois être capable de construire et de déployer l'application à partir de zéro, sans regarder une machine de développement ou de production.

18
Stu Thompson

La meilleure pratique que j'ai vue consiste à créer un script de génération pour supprimer et reconstruire votre base de données sur un serveur de transfert. Chaque itération a reçu un dossier pour les modifications de la base de données, toutes les modifications ont été écrites avec "Drop ... Create". De cette manière, vous pouvez revenir à tout moment à une version antérieure en pointant la construction sur le dossier dans lequel vous souhaitez utiliser la version.

Je crois que cela a été fait avec NaNt/CruiseControl.

14
Sara Chipps

OUI, je pense qu'il est important de mettre à jour votre base de données. Pas les données, mais le schéma pour certains.

Dans Ruby on Rails, cela est géré par la structure avec "migrations". Chaque fois que vous modifiez la base de données, vous créez un script qui applique les modifications et vous l'enregistrez dans le contrôle de source.

Mon magasin a tellement aimé cette idée que nous avons ajouté la fonctionnalité à notre version Java en utilisant des scripts Shell et Ant. Nous avons intégré le processus à notre routine de déploiement. Il serait assez facile d'écrire des scripts pour faire la même chose dans d'autres frameworks qui ne prennent pas en charge le contrôle de version de base de données.

11
Pete

Les nouveaux projets de base de données dans Visual Studio fournissent des scripts de contrôle de code source et de modification.

Ils ont un outil Nice qui compare les bases de données et peut générer un script qui convertit le schéma de l’un en l’autre, ou met à jour les données d’une sur l’autre.

Le schéma de base de données est "détruit" pour créer de très nombreux petits fichiers .sql, un par commande DDL décrivant la base de données.

+ tom


Informations supplémentaires 2008-11-30

Je l'utilise en tant que développeur depuis un an et je l'aime vraiment beaucoup. Il est facile de comparer mon travail de développeur à la production et de générer un script à utiliser pour la publication. Je ne sais pas s'il manque des fonctionnalités nécessaires aux administrateurs de base de données pour les projets de type "entreprise".

Le schéma étant "déchiqueté" dans des fichiers SQL, le contrôle de source fonctionne correctement.

Un des pièges est que vous devez avoir un état d'esprit différent lorsque vous utilisez un projet de base de données. L'outil a un "projet de base de données" dans VS, qui est juste le sql, plus une base de données locale générée automatiquement qui contient le schéma et d'autres données administratives - mais aucune des données de votre application, plus votre base de développement locale que vous utilisez pour application de travail de dev de données. Vous connaissez rarement la base de données générée automatiquement, mais vous devez la connaître afin de pouvoir la laisser toute seule :). Cette db spéciale est clairement reconnaissable car elle porte un Guid dans son nom,

Le projet de base de données VS fait un travail intéressant en intégrant les modifications apportées à la base de données par d’autres membres de l’équipe dans votre projet local/la base de données associée. mais vous devez prendre une mesure supplémentaire pour comparer le schéma de projet avec votre schéma de base de données dev local et appliquer les mods. Cela a du sens, mais cela semble maladroit au début.

Les projets DB sont un outil très puissant. Ils génèrent non seulement des scripts, mais peuvent les appliquer immédiatement. Veillez à ne pas détruire votre base de données de production avec elle. ;)

J'aime beaucoup les projets de base de données VS et je compte utiliser cet outil pour tous mes projets de base de données.

+ tom

8
Tom A

Demander aux équipes de développement d’utiliser un système de gestion de contrôle de source de base de données SQL n’est pas la solution miracle qui permettra d’éviter les problèmes. À lui seul, le contrôle de source de base de données introduit une surcharge supplémentaire, car les développeurs doivent enregistrer les modifications apportées à un objet dans un script SQL distinct, ouvrir le client du système de contrôle de code source, archiver le fichier de script SQL à l'aide du client, puis appliquer les modifications à la base de données en direct.

Je peux suggérer d'utiliser le complément SSMS appelé ApexSQL Source Control . Il permet aux développeurs de mapper facilement les objets de base de données avec le système de contrôle de source via l'assistant directement à partir de SSMS. Le complément inclut la prise en charge de TFS, Git, Subversion et d’autres systèmes SC. Il inclut également un support pour le contrôle de source des données statiques.

Après avoir téléchargé et installé ApexSQL Source Control, cliquez simplement avec le bouton droit de la souris sur la base de données sur laquelle vous souhaitez contrôler le contrôle de version et accédez au sous-menu ApexSQL Source Control dans SSMS. Cliquez sur l'option Lier la base de données au contrôle de source, sélectionnez le système de contrôle de source et le modèle de développement. Après cela, vous devrez fournir les informations de connexion et la chaîne de référentiel pour le système de contrôle de source que vous avez choisi.

Vous pouvez lire cet article pour plus d'informations: http://solutioncenter.apexsql.com/sql-source-control-reduce-database-development- time/

8
AliceF

Nous contrôlons tous nos objets créés avec la base de données. Et juste pour garder les développeurs honnêtes (parce que vous pouvez créer des objets sans qu'ils soient dans le contrôle de code source), nos dbas recherchent périodiquement tout ce qui n’est pas dans le contrôle de code source et s’ils trouvent quelque chose, ils le suppriment sans demander s’il est ok.

6
HLGEM

Je le fais en sauvegardant des scripts de création/mise à jour et un script qui génère des données d'échantillonnage.

6
Paco

Oui, nous le faisons en conservant notre code SQL dans notre construction - nous gardons DROP.sql, CREATE.sql, USERS.sql, VALUES.sql et le contrôle de version, afin de pouvoir revenir à n’importe quelle version marquée.

Nous avons également des tâches ant qui peuvent recréer la base de données à tout moment.

De plus, le code SQL est ensuite étiqueté avec votre code source qui va avec.

6
DustinB

Le schéma le plus efficace que j'ai jamais utilisé dans un projet combine des sauvegardes et des fichiers SQL différentiels. Fondamentalement, nous effectuions une sauvegarde de notre base de données après chaque publication et effectuions un dump SQL afin de pouvoir créer un schéma vierge à partir de zéro si nous en avions également besoin. Ensuite, chaque fois que vous avez besoin de modifier la base de données, vous ajoutez un script de remplacement dans le répertoire SQL sous contrôle de version. Nous apposerions toujours un numéro de séquence ou une date sur le nom du fichier, de sorte que le premier changement ressemblerait à 01_add_created_on_column.sql et que le prochain script serait 02_added_customers_index. Notre machine CI vérifiait ces problèmes et les exécutait de manière séquentielle sur une nouvelle copie de la base de données restaurée à partir de la sauvegarde.

Nous avons également mis en place des scripts que les développeurs pourraient utiliser pour réinitialiser leur base de données locale sur la version actuelle à l'aide d'une seule commande.

6
Mike Deck

J'utilise SchemaBank pour contrôler la version de tous mes changements de schéma de base de données:

  • à partir du jour 1, j'importe mon fichier de schéma db
  • j'ai commencé à modifier la conception de mon schéma à l'aide d'un navigateur Web (car ils sont SaaS/cloud-based)
  • quand je veux mettre à jour mon serveur de base de données, je génère le script de changement (SQL) à partir de celui-ci et l'applique à la base de données. Dans Schemabank, ils m'obligent à valider mon travail avant de pouvoir générer un script de mise à jour. J'aime ce genre de pratique afin de pouvoir toujours remonter au besoin.

Notre règle d'équipe est de NE JAMAIS toucher le serveur de base de données directement sans stocker le travail de conception au préalable. Mais il arrive que quelqu'un puisse être tenté d'enfreindre la règle, pour des raisons pratiques. Nous voudrions importer à nouveau le vidage de schéma dans Schemabank et le laisser faire le diff et le bash si une anomalie est trouvée. Bien que nous puissions générer les scripts de modification à partir de celui-ci pour synchroniser notre conception de base de données et notre schéma, nous ne le supportons pas.

À propos, ils nous ont également laissé créer des branches dans l’arbre de contrôle de version afin que je puisse en maintenir une pour la mise en attente et une pour la production. Et un pour coder le bac à sable.

Un outil de conception de schéma Web très soigné avec contrôle de version et gestion du changement.

5
Leigh Pyle

J'utilise des scripts SQL CREATE exportés de MySQL Workbech, puis en utilisant la fonctionnalité "Export SQL ALTER", ils aboutissent à une série de scripts de création (numérotés bien sûr) et aux scripts de modification pouvant appliquer les modifications entre eux.

3.- Export SQL ALTER script Normalement, vous devez maintenant écrire manuellement les instructions ALTER TABLE, en tenant compte des modifications que vous avez apportées au modèle. Mais vous pouvez être intelligent et laisser Workbench faire le travail dur pour vous. Sélectionnez simplement Fichier -> Exporter -> Forward Engineer SQL ALTER Script… dans le menu principal.

Cela vous invitera à spécifier le fichier SQL CREATE auquel le modèle actuel doit être comparé.

Sélectionnez le script SQL CREATE à l'étape 1. L'outil génère ensuite le script ALTER TABLE pour vous et vous pouvez exécuter ce script sur votre base de données pour le mettre à jour.

Vous pouvez le faire en utilisant le navigateur de requêtes MySQL ou le client mysql.Voila! Votre modèle et votre base de données sont maintenant synchronisés!

Source: MySQL Workbench Community Edition: Guide de synchronisation de schémas

Tous ces scripts sont bien sûr sous contrôle de version.

4
levhita

Si votre base de données est SQL Server, nous avons peut-être la solution que vous recherchez. SQL Source Control 1.0 est maintenant disponible.

http://www.red-gate.com/products/SQL_Source_Control/index.htm

Cela s’intègre à SSMS et fournit le lien entre vos objets de base de données et votre VCS. La "sortie de script" se déroule de manière transparente (le moteur de comparaison SQL est installé sous le capot), ce qui devrait rendre l'utilisation du logiciel tellement simple que les développeurs ne seront pas découragés d'adopter le processus.

Une autre solution Visual Studio est ReadyRoll , implémentée en tant que sous-type du projet de base de données SSDT. Cela repose sur une approche axée sur les migrations, mieux adaptée aux besoins en automatisation des équipes de DevOps.

4
David Atkinson

Il y a eu beaucoup de discussions sur le modèle de base de données lui-même, mais nous conservons également les données requises dans des fichiers .SQL.

Par exemple, pour être utile, votre application pourrait en avoir besoin lors de l'installation:

INSERT INTO Currency (CurrencyCode, CurrencyName) 
VALUES ('AUD', 'Australian Dollars');

INSERT INTO Currency (CurrencyCode, CurrencyName) 
VALUES ('USD', 'US Dollars');

Nous aurions un fichier appelé currency.sql sous Subversion. En tant qu'étape manuelle du processus de construction, nous comparons l'ancien currency.sql au dernier et écrivons un script de mise à niveau.

4
WW.

Oui toujours. Vous devriez être en mesure de recréer la structure de votre base de données de production avec un ensemble utile d'exemples de données, le cas échéant. Si vous ne le faites pas, avec le temps, des modifications mineures pour que tout fonctionne correctement sont oubliées, puis un jour, vous serez piqué, très fort. C'est l'assurance dont vous ne pensez peut-être pas avoir besoin, mais le jour où vous le faites, le prix en vaut 10 fois plus!

4
AndrewB

J'ai tout le nécessaire pour recréer ma DB à partir de métal nu, moins les données elles-mêmes. Je suis sûr qu'il existe de nombreuses façons de le faire, mais tous mes scripts et autres sont stockés dans Subversion et nous pouvons reconstruire la structure de la base de données, par exemple en extrayant tout cela de Subversion et en exécutant un programme d'installation.

4
itsmatt

Nous contrôlons la version et la source de tout ce qui entoure nos bases de données:

  • DDL (crée et modifie)
  • DML (données de référence, codes, etc.)
  • Modifications du modèle de données (avec ERwin ou ER/Studio)
  • Modifications de la configuration de la base de données (autorisations, objets de sécurité, modifications de configuration générales)

Nous faisons tout cela avec des tâches automatisées à l'aide de Change Manager et de scripts personnalisés. Le gestionnaire des modifications surveille ces modifications et les avertit lorsqu'elles sont effectuées.

4
Karen Lopez

Généralement, je crée un script SQL pour chaque modification apportée et un autre pour annuler ces modifications et conserver ces scripts sous contrôle de version.

Ensuite, nous avons le moyen de créer une nouvelle base de données mise à jour à la demande et nous pouvons facilement passer d’une révision à l’autre. Chaque fois que nous publions une version, nous assemblons les scripts (cela demande un peu de travail manuel, mais il s’agit rarement de difficile). Nous avons donc un ensemble de scripts pouvant convertir les versions.

Oui, avant que vous ne le disiez, ceci est très similaire à celui que Rails et à d'autres le font, mais cela semble fonctionner plutôt bien.

4
Dan

Je pense que chaque base de données doit être sous contrôle de source et que les développeurs doivent pouvoir créer facilement leur base de données locale. Inspiré de Visual Studio pour les professionnels de la base de données, j'ai créé un outil open source qui écrit des bases de données MS SQL et fournit un moyen simple de les déployer sur votre moteur de base de données local. Essayez http://dbsourcetools.codeplex.com/ . Amusez-vous bien, Nathan.

4
Nathan Rozentals

Voici un exemple de solution d’un homme pauvre pour un déclencheur implémentant le suivi des modifications d’objets de base de données (via des déclarations DDL) sur une base de données SQL Server 2005/2008. Je contient également un exemple simple d'utilisation pratique de l'utilisation de la balise xml someValue requise dans le code source pour chaque commande SQL exécutée sur la base de données + suivi de la version actuelle de la base de données et de son type (dev, test, qa, fb, prod ) On pourrait l’étendre avec des attributs supplémentaires requis tels que, etc. Le code est plutôt long: il crée la base de données vide + la structure de table de suivi requise + les fonctions de base de données requises et le déclencheur de remplissage s’exécutant tous sous un schéma [ga].

USE [master]
GO

/****** Object:  Database [DBGA_DEV]    Script Date: 04/22/2009 13:22:01 ******/
CREATE DATABASE [DBGA_DEV] ON  PRIMARY 
( NAME = N'DBGA_DEV', FILENAME = N'D:\GENAPP\DATA\DBFILES\DBGA_DEV.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
 LOG ON 
( NAME = N'DBGA_DEV_log', FILENAME = N'D:\GENAPP\DATA\DBFILES\DBGA_DEV_log.ldf' , SIZE = 6208KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO

ALTER DATABASE [DBGA_DEV] SET COMPATIBILITY_LEVEL = 100
GO

IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [DBGA_DEV].[dbo].[sp_fulltext_database] @action = 'enable'
end
GO

ALTER DATABASE [DBGA_DEV] SET ANSI_NULL_DEFAULT OFF 
GO

ALTER DATABASE [DBGA_DEV] SET ANSI_NULLS OFF 
GO

ALTER DATABASE [DBGA_DEV] SET ANSI_PADDING ON 
GO

ALTER DATABASE [DBGA_DEV] SET ANSI_WARNINGS OFF 
GO

ALTER DATABASE [DBGA_DEV] SET ARITHABORT OFF 
GO

ALTER DATABASE [DBGA_DEV] SET AUTO_CLOSE OFF 
GO

ALTER DATABASE [DBGA_DEV] SET AUTO_CREATE_STATISTICS ON 
GO

ALTER DATABASE [DBGA_DEV] SET AUTO_SHRINK OFF 
GO

ALTER DATABASE [DBGA_DEV] SET AUTO_UPDATE_STATISTICS ON 
GO

ALTER DATABASE [DBGA_DEV] SET CURSOR_CLOSE_ON_COMMIT OFF 
GO

ALTER DATABASE [DBGA_DEV] SET CURSOR_DEFAULT  GLOBAL 
GO

ALTER DATABASE [DBGA_DEV] SET CONCAT_NULL_YIELDS_NULL OFF 
GO

ALTER DATABASE [DBGA_DEV] SET NUMERIC_ROUNDABORT OFF 
GO

ALTER DATABASE [DBGA_DEV] SET QUOTED_IDENTIFIER OFF 
GO

ALTER DATABASE [DBGA_DEV] SET RECURSIVE_TRIGGERS OFF 
GO

ALTER DATABASE [DBGA_DEV] SET  DISABLE_BROKER 
GO

ALTER DATABASE [DBGA_DEV] SET AUTO_UPDATE_STATISTICS_ASYNC OFF 
GO

ALTER DATABASE [DBGA_DEV] SET DATE_CORRELATION_OPTIMIZATION OFF 
GO

ALTER DATABASE [DBGA_DEV] SET TRUSTWORTHY OFF 
GO

ALTER DATABASE [DBGA_DEV] SET ALLOW_SNAPSHOT_ISOLATION OFF 
GO

ALTER DATABASE [DBGA_DEV] SET PARAMETERIZATION SIMPLE 
GO

ALTER DATABASE [DBGA_DEV] SET READ_COMMITTED_SNAPSHOT OFF 
GO

ALTER DATABASE [DBGA_DEV] SET HONOR_BROKER_PRIORITY OFF 
GO

ALTER DATABASE [DBGA_DEV] SET  READ_WRITE 
GO

ALTER DATABASE [DBGA_DEV] SET RECOVERY FULL 
GO

ALTER DATABASE [DBGA_DEV] SET  MULTI_USER 
GO

ALTER DATABASE [DBGA_DEV] SET PAGE_VERIFY CHECKSUM  
GO

ALTER DATABASE [DBGA_DEV] SET DB_CHAINING OFF 
GO

EXEC [DBGA_DEV].sys.sp_addextendedproperty @name=N'DbType', @value=N'DEV' 
GO

EXEC [DBGA_DEV].sys.sp_addextendedproperty @name=N'DbVersion', @value=N'0.0.1.20090414.1100' 
GO



USE [DBGA_DEV]
GO
/****** Object:  Schema [ga]    Script Date: 04/22/2009 13:21:29 ******/
CREATE SCHEMA [ga] AUTHORIZATION [dbo]
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Contains the objects of the Generic Application database' , @level0type=N'SCHEMA',@level0name=N'ga'
GO
/****** Object:  Table [ga].[tb_DataMeta_ObjChangeLog]    Script Date: 04/22/2009 13:21:40 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [ga].[tb_DataMeta_ObjChangeLog](
    [LogId] [int] IDENTITY(1,1) NOT NULL,
    [TimeStamp] [timestamp] NOT NULL,
    [DatabaseName] [varchar](256) NOT NULL,
    [SchemaName] [varchar](256) NOT NULL,
    [DbVersion] [varchar](20) NOT NULL,
    [DbType] [varchar](20) NOT NULL,
    [EventType] [varchar](50) NOT NULL,
    [ObjectName] [varchar](256) NOT NULL,
    [ObjectType] [varchar](25) NOT NULL,
    [Version] [varchar](50) NULL,
    [SqlCommand] [varchar](max) NOT NULL,
    [EventDate] [datetime] NOT NULL,
    [LoginName] [varchar](256) NOT NULL,
    [FirstName] [varchar](256) NULL,
    [LastName] [varchar](50) NULL,
    [ChangeDescription] [varchar](1000) NULL,
    [Description] [varchar](1000) NULL,
    [ObjVersion] [varchar](20) NOT NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The database version as written in the extended prop of the database' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'TABLE',@level1name=N'tb_DataMeta_ObjChangeLog', @level2type=N'COLUMN',@level2name=N'DbVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'dev , test , qa , fb or prod' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'TABLE',@level1name=N'tb_DataMeta_ObjChangeLog', @level2type=N'COLUMN',@level2name=N'DbType'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The name of the object as it is registered in the sys.objects ' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'TABLE',@level1name=N'tb_DataMeta_ObjChangeLog', @level2type=N'COLUMN',@level2name=N'ObjectName'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'TABLE',@level1name=N'tb_DataMeta_ObjChangeLog', @level2type=N'COLUMN',@level2name=N'Description'
GO
SET IDENTITY_INSERT [ga].[tb_DataMeta_ObjChangeLog] ON
INSERT [ga].[tb_DataMeta_ObjChangeLog] ([LogId], [DatabaseName], [SchemaName], [DbVersion], [DbType], [EventType], [ObjectName], [ObjectType], [Version], [SqlCommand], [EventDate], [LoginName], [FirstName], [LastName], [ChangeDescription], [Description], [ObjVersion]) VALUES (3, N'DBGA_DEV', N'en', N'0.0.1.20090414.1100', N'DEV', N'DROP_TABLE', N'tb_BL_Products', N'TABLE', N' some', N'<EVENT_INSTANCE><EventType>DROP_TABLE</EventType><PostTime>2009-04-22T11:03:11.880</PostTime><SPID>57</SPID><ServerName>YSG</ServerName><LoginName>ysg\yordgeor</LoginName><UserName>dbo</UserName><DatabaseName>DBGA_DEV</DatabaseName><SchemaName>en</SchemaName><ObjectName>tb_BL_Products</ObjectName><ObjectType>TABLE</ObjectType><TSQLCommand><SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE"/><CommandText>drop TABLE [en].[tb_BL_Products] --<Version> some</Version>&#x0D;
</CommandText></TSQLCommand></EVENT_INSTANCE>', CAST(0x00009BF300B6271C AS DateTime), N'ysg\yordgeor', N'Yordan', N'Georgiev', NULL, NULL, N'0.0.0')
INSERT [ga].[tb_DataMeta_ObjChangeLog] ([LogId], [DatabaseName], [SchemaName], [DbVersion], [DbType], [EventType], [ObjectName], [ObjectType], [Version], [SqlCommand], [EventDate], [LoginName], [FirstName], [LastName], [ChangeDescription], [Description], [ObjVersion]) VALUES (4, N'DBGA_DEV', N'en', N'0.0.1.20090414.1100', N'DEV', N'CREATE_TABLE', N'tb_BL_Products', N'TABLE', N' 2.2.2 ', N'<EVENT_INSTANCE><EventType>CREATE_TABLE</EventType><PostTime>2009-04-22T11:03:18.620</PostTime><SPID>57</SPID><ServerName>YSG</ServerName><LoginName>ysg\yordgeor</LoginName><UserName>dbo</UserName><DatabaseName>DBGA_DEV</DatabaseName><SchemaName>en</SchemaName><ObjectName>tb_BL_Products</ObjectName><ObjectType>TABLE</ObjectType><TSQLCommand><SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE"/><CommandText>CREATE TABLE [en].[tb_BL_Products](&#x0D;
    [ProducId] [int] NULL,&#x0D;
    [ProductName] [nchar](10) NULL,&#x0D;
    [ProductDescription] [varchar](5000) NULL&#x0D;
) ON [PRIMARY]&#x0D;
/*&#x0D;
<Version> 2.2.2 </Version>&#x0D;
&#x0D;
*/&#x0D;
</CommandText></TSQLCommand></EVENT_INSTANCE>', CAST(0x00009BF300B62F07 AS DateTime), N'ysg\yordgeor', N'Yordan', N'Georgiev', NULL, NULL, N'0.0.0')
INSERT [ga].[tb_DataMeta_ObjChangeLog] ([LogId], [DatabaseName], [SchemaName], [DbVersion], [DbType], [EventType], [ObjectName], [ObjectType], [Version], [SqlCommand], [EventDate], [LoginName], [FirstName], [LastName], [ChangeDescription], [Description], [ObjVersion]) VALUES (5, N'DBGA_DEV', N'en', N'0.0.1.20090414.1100', N'DEV', N'DROP_TABLE', N'tb_BL_Products', N'TABLE', N' 2.2.2 ', N'<EVENT_INSTANCE><EventType>DROP_TABLE</EventType><PostTime>2009-04-22T11:25:12.620</PostTime><SPID>57</SPID><ServerName>YSG</ServerName><LoginName>ysg\yordgeor</LoginName><UserName>dbo</UserName><DatabaseName>DBGA_DEV</DatabaseName><SchemaName>en</SchemaName><ObjectName>tb_BL_Products</ObjectName><ObjectType>TABLE</ObjectType><TSQLCommand><SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE"/><CommandText>drop TABLE [en].[tb_BL_Products] &#x0D;
</CommandText></TSQLCommand></EVENT_INSTANCE>', CAST(0x00009BF300BC32F1 AS DateTime), N'ysg\yordgeor', N'Yordan', N'Georgiev', NULL, NULL, N'0.0.0')
INSERT [ga].[tb_DataMeta_ObjChangeLog] ([LogId], [DatabaseName], [SchemaName], [DbVersion], [DbType], [EventType], [ObjectName], [ObjectType], [Version], [SqlCommand], [EventDate], [LoginName], [FirstName], [LastName], [ChangeDescription], [Description], [ObjVersion]) VALUES (6, N'DBGA_DEV', N'en', N'0.0.1.20090414.1100', N'DEV', N'CREATE_TABLE', N'tb_BL_Products', N'TABLE', N' 2.2.2 ', N'<EVENT_INSTANCE><EventType>CREATE_TABLE</EventType><PostTime>2009-04-22T11:25:19.053</PostTime><SPID>57</SPID><ServerName>YSG</ServerName><LoginName>ysg\yordgeor</LoginName><UserName>dbo</UserName><DatabaseName>DBGA_DEV</DatabaseName><SchemaName>en</SchemaName><ObjectName>tb_BL_Products</ObjectName><ObjectType>TABLE</ObjectType><TSQLCommand><SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE"/><CommandText>CREATE TABLE [en].[tb_BL_Products](&#x0D;
    [ProducId] [int] NULL,&#x0D;
    [ProductName] [nchar](10) NULL,&#x0D;
    [ProductDescription] [varchar](5000) NULL&#x0D;
) ON [PRIMARY]&#x0D;
/*&#x0D;
<Version> 2.2.2 </Version>&#x0D;
&#x0D;
*/&#x0D;
</CommandText></TSQLCommand></EVENT_INSTANCE>', CAST(0x00009BF300BC3A69 AS DateTime), N'ysg\yordgeor', N'Yordan', N'Georgiev', NULL, NULL, N'0.0.0')
SET IDENTITY_INSERT [ga].[tb_DataMeta_ObjChangeLog] OFF
/****** Object:  Table [ga].[tb_BLSec_LoginsForUsers]    Script Date: 04/22/2009 13:21:40 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [ga].[tb_BLSec_LoginsForUsers](
    [LoginsForUsersId] [int] IDENTITY(1,1) NOT NULL,
    [LoginName] [nvarchar](100) NOT NULL,
    [FirstName] [varchar](100) NOT NULL,
    [SecondName] [varchar](100) NULL,
    [LastName] [varchar](100) NOT NULL,
    [DomainName] [varchar](100) NOT NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
SET IDENTITY_INSERT [ga].[tb_BLSec_LoginsForUsers] ON
INSERT [ga].[tb_BLSec_LoginsForUsers] ([LoginsForUsersId], [LoginName], [FirstName], [SecondName], [LastName], [DomainName]) VALUES (1, N'ysg\yordgeor', N'Yordan', N'Stanchev', N'Georgiev', N'yordgeor')
SET IDENTITY_INSERT [ga].[tb_BLSec_LoginsForUsers] OFF
/****** Object:  Table [en].[tb_BL_Products]    Script Date: 04/22/2009 13:21:40 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [en].[tb_BL_Products](
    [ProducId] [int] NULL,
    [ProductName] [nchar](10) NULL,
    [ProductDescription] [varchar](5000) NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object:  StoredProcedure [ga].[procUtils_SqlCheatSheet]    Script Date: 04/22/2009 13:21:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [ga].[procUtils_SqlCheatSheet]                

as                 
set nocount on                 

--what was the name of the table with something like role                
/*                
SELECT * from sys.tables where [name] like '%POC%'                
*/                
-- what are the columns of this table                 
/*                
select column_name , DATA_TYPE , CHARACTER_MAXIMUM_LENGTH,  table_name  from Information_schema.columns where table_name='tbGui_ExecutePOC'                
*/                

-- find proc        
--what was the name of procedure with something like role                
/*                
select * from sys.procedures where [name] like '%ext%'                
exec sp_HelpText procName        
*/                
/*                
exec sp_helpText procUtils_InsertGenerator                
*/                
--how to list all databases in sql server                 
/*                
SELECT database_id AS ID, NULL AS ParentID, name AS Text FROM sys.databases ORDER BY [name]                
*/                

--HOW-TO LIST ALL TABLES IN A SQL SERVER 2005 DATABASE                
/*                
SELECT TABLE_NAME FROM [POC].INFORMATION_SCHEMA.TABLES                
WHERE TABLE_TYPE = 'BASE TABLE'                  
AND TABLE_NAME <> 'dtproperties'                  
ORDER BY TABLE_NAME                


*/                
--HOW-TO ENABLE XP_CMDSHELL START                
-------------------------------------------------------------------------                
-- configure verbose mode temporarily                 
-- EXECUTE sp_configure 'show advanced options', 1                 
-- RECONFIGURE WITH OVERRIDE                 
--GO                 


--ENABLE xp_cmdshell                 
-- EXECUTE sp_configure 'xp_cmdshell', '1'                 
-- RECONFIGURE WITH OVERRIDE                 
-- EXEC SP_CONFIGURE 'show advanced option', '1';                 
-- SHOW THE CONFIGURATION                 
-- EXEC SP_CONFIGURE;                 


--turn show advance options off                 
-- GO                 
--EXECUTE sp_configure 'show advanced options', 0                 
-- RECONFIGURE WITH OVERRIDE                 
-- GO                

--HOW-TO ENABLE XP_CMDSHELL END                
-------------------------------------------------------------------------                

--HOW-TO IMPLEMENT SLEEP                 
-- sleep for 10 seconds                 
-- WAITFOR DELAY '00:00:10' SELECT * FROM My_Table                

/* LIST ALL PRIMARY KEYS                 

SELECT                 
  INFORMATION_SCHEMA.TABLE_CONSTRAINTS.TABLE_NAME AS TABLE_NAME,                
  INFORMATION_SCHEMA.KEY_COLUMN_USAGE.COLUMN_NAME AS COLUMN_NAME,                 
  REPLACE(INFORMATION_SCHEMA.TABLE_CONSTRAINTS.CONSTRAINT_TYPE,' ', '_') AS CONSTRAINT_TYPE                 
FROM                 
  INFORMATION_SCHEMA.TABLE_CONSTRAINTS                 
  INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ON                 
  INFORMATION_SCHEMA.TABLE_CONSTRAINTS.CONSTRAINT_NAME =                 
  INFORMATION_SCHEMA.KEY_COLUMN_USAGE.CONSTRAINT_NAME                 
WHERE                 
  INFORMATION_SCHEMA.TABLE_CONSTRAINTS.TABLE_NAME <> N'sysdiagrams'                 
ORDER BY                 
  INFORMATION_SCHEMA.TABLE_CONSTRAINTS.TABLE_NAME ASC                

*/                

--HOW-TO COPY TABLE AND THE WHOLE TABLE DATA , COPY TABLE FROM DB TO DB                
--==================================================START                 
/*                
use Poc_Dev                
go                
drop table tbGui_LinksVisibility                

use POc_test                
go                
select *                 
INTO [POC_Dev].[ga].[tbGui_LinksVisibility]                
from [POC_TEST].[ga].[tbGui_LinksVisibility]                


*/                
--HOW-TO COPY TABLE AND THE WHOLE TABLE DATA , COPY TABLE FROM DB TO DB                
--====================================================END                
--=================================================== SEE TABLE METADATA START                
/*                



SELECT c.name AS [COLUMN_NAME], sc.data_type AS [DATA_TYPE], [value] AS                 
[DESCRIPTION] , c.max_length as [MAX_LENGTH] , c.is_nullable AS [OPTIONAL]                 
, c.is_identity AS [IS_PRIMARY_KEY] FROM sys.extended_properties AS ep                 
INNER JOIN sys.tables AS t ON ep.major_id = t.object_id                 
INNER JOIN sys.columns AS c ON ep.major_id = c.object_id AND ep.minor_id                 
= c.column_id                 
INNER JOIN INFORMATION_SCHEMA.COLUMNS sc ON t.name = sc.table_name and                 
c.name = sc.column_name                 
WHERE class = 1 and t.name = 'tbGui_ExecutePOC' ORDER BY SC.DATA_TYPE                


*/                
--=================================================== SEE TABLE METADATA END               
    /*            
select * from Information_schema.columns                
select table_name , column_name from Information_schema.columns where table_name='tbGui_Wizards'                
    */            


--=================================================== LIST ALL TABLES AND THEIR DESCRIPTOINS START                
/*                

SELECT T.name AS TableName, CAST(Props.value AS varchar(1000)) AS                
TableDescription                
FROM sys.tables AS T LEFT OUTER JOIN                
(SELECT class, class_desc, major_id, minor_id,                
name, value                
FROM sys.extended_properties                
WHERE (minor_id = 0) AND (class = 1)) AS                
Props ON T.object_id = Props.major_id                
WHERE (T.type = 'U') AND (T.name <> N'sysdiagrams')                
ORDER BY TableName                
*/                
--=================================================== LIST ALL TABLES AND THEIR DESCRIPTOINS START                

--=================================================== LIST ALL OBJECTS FROM DB START                
/*                


use DB                
--HOW-TO LIST ALL PROCEDURE IN A DATABASE                
select s.name from sysobjects s where type = 'P'                
--HOW-TO LIST ALL TRIGGERS BY NAME IN A DATABASE                
select s.name from sysobjects s where type = 'TR'                
--HOW-TO LIST TABLES IN A DATABASE                 
select s.name from sysobjects s where type = 'U'                
--how-to list all system tables in a database                
select s.name from sysobjects s where type = 's'                
--how-to list all the views in a database                
select s.name from sysobjects s where type = 'v'                


*/                

/*                
Similarly you can find out other objects created by user, simple change type =                 

C = CHECK constraint                 

D = Default or DEFAULT constraint                 

F = FOREIGN KEY constraint                 

L = Log                 

FN = Scalar function                 

IF = In-lined table-function                 

P = Stored procedure                 

PK = PRIMARY KEY constraint (type is K)                 

RF = Replication filter stored procedure                

S = System table                 

TF = Table function                 

TR = Trigger                 

U = User table ( this is the one I discussed above in the example)                

UQ = UNIQUE constraint (type is K)                 

V = View                 

X = Extended stored procedure                
*/                



--=================================================== HOW-TO SEE ALL MY PERMISSIONS START                


/*                

SELECT * FROM fn_my_permissions(NULL, 'SERVER');                
USE poc_qa;                
SELECT * FROM fn_my_permissions (NULL, 'database');                
GO                

*/                
--=================================================== HOW-TO SEE ALL MY PERMISSIONS END                

/*               
--find table               

use poc_dev               
go               
select s.name from sysobjects s where type = 'u'  and s.name like '%Visibility%'              
select * from tbGui_LinksVisibility              

*/              

/* find cursor              

use poc      
go        
DECLARE @procName varchar(100)        
DECLARE @cursorProcNames CURSOR        
SET @cursorProcNames = CURSOR FOR        
select name from sys.procedures where modify_date > '2009-02-05 13:12:15.273' order by modify_date desc       

OPEN @cursorProcNames        
FETCH NEXT        
FROM @cursorProcNames INTO @procName        
WHILE @@FETCH_STATUS = 0        
BEGIN        

set nocount off;        
exec sp_HelpText @procName --- or print them        
-- print @procName        

FETCH NEXT        
FROM @cursorProcNames INTO @procName        
END        
CLOSE @cursorProcNames        

select @@error    

*/              


/* --  SEE STORED PROCEDURE EXT PROPS            

SELECT ep.name as 'EXT_PROP_NAME' , SP.NAME , [value] as 'DESCRIPTION' FROM sys.extended_properties as ep left join sys.procedures as sp on sp.object_id = ep.major_id where sp.type='P'            


-- what the hell I ve been doing lately on sql server 2005 / 2008
select o.name , 
(SELECT [definition] AS [text()] FROM sys.all_sql_modules where sys.all_sql_modules.object_id=a.object_id FOR XML PATH(''), TYPE) AS Statement_Text
, a.object_id, o.modify_date from sys.all_sql_modules a left join sys.objects o on a.object_id=o.object_id order by 4 desc



-- GET THE RIGHT LANG SCHEMA START 
DECLARE @template AS varchar(max)
SET @template = 'SELECT * FROM {object_name}'

DECLARE @object_name AS sysname

SELECT @object_name = QUOTENAME(s.name) + '.' + QUOTENAME(o.name)
FROM sys.objects o
INNER JOIN sys.schemas s
    ON s.schema_id = o.schema_id
WHERE o.object_id = OBJECT_ID(QUOTENAME(@LANG) + '.[TestingLanguagesInNameSpacesDelMe]')

IF @object_name IS NOT NULL
BEGIN
    DECLARE @sql AS varchar(max)
    SET @sql = REPLACE(@template, '{object_name}', @object_name)
    EXEC (@sql)
END
-- GET THE RIGHT LANG SCHEMA END 

--  SEE STORED PROCEDURE EXT PROPS end*/             
set nocount off
GO
EXEC sys.sp_addextendedproperty @name=N'AuthorName', @value=N'Yordan Georgiev' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'PROCEDURE',@level1name=N'procUtils_SqlCheatSheet'
GO
EXEC sys.sp_addextendedproperty @name=N'ProcDescription', @value=N'TODO:ADD HERE DESCRPIPTION' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'PROCEDURE',@level1name=N'procUtils_SqlCheatSheet'
GO
EXEC sys.sp_addextendedproperty @name=N'ProcVersion', @value=N'0.1.0.20090406.1317' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'PROCEDURE',@level1name=N'procUtils_SqlCheatSheet'
GO
/****** Object:  UserDefinedFunction [ga].[GetDbVersion]    Script Date: 04/22/2009 13:21:42 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [ga].[GetDbVersion]()
RETURNS VARCHAR(20)
    BEGIN
        RETURN convert(varchar(20) , (select value from sys.extended_properties where name='DbVersion' and class_desc='DATABASE') )
    END
GO
EXEC sys.sp_addextendedproperty @name=N'AuthorName', @value=N'Yordan Georgiev' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'FUNCTION',@level1name=N'GetDbVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'ChangeDescription', @value=N'Initial creation' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'FUNCTION',@level1name=N'GetDbVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'CreatedWhen', @value=N'getDate()' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'FUNCTION',@level1name=N'GetDbVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'Description', @value=N'Gets the current version of the database ' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'FUNCTION',@level1name=N'GetDbVersion'
GO
/****** Object:  UserDefinedFunction [ga].[GetDbType]    Script Date: 04/22/2009 13:21:42 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [ga].[GetDbType]()
RETURNS VARCHAR(30)
    BEGIN
        RETURN convert(varchar(30) , (select value from sys.extended_properties where name='DbType' and class_desc='DATABASE') )
    END
GO
/****** Object:  Default [DF_tb_DataMeta_ObjChangeLog_DbVersion]    Script Date: 04/22/2009 13:21:40 ******/
ALTER TABLE [ga].[tb_DataMeta_ObjChangeLog] ADD  CONSTRAINT [DF_tb_DataMeta_ObjChangeLog_DbVersion]  DEFAULT ('select ga.GetDbVersion()') FOR [DbVersion]
GO
/****** Object:  Default [DF_tb_DataMeta_ObjChangeLog_EventDate]    Script Date: 04/22/2009 13:21:40 ******/
ALTER TABLE [ga].[tb_DataMeta_ObjChangeLog] ADD  CONSTRAINT [DF_tb_DataMeta_ObjChangeLog_EventDate]  DEFAULT (getdate()) FOR [EventDate]
GO
/****** Object:  Default [DF_tb_DataMeta_ObjChangeLog_ObjVersion]    Script Date: 04/22/2009 13:21:40 ******/
ALTER TABLE [ga].[tb_DataMeta_ObjChangeLog] ADD  CONSTRAINT [DF_tb_DataMeta_ObjChangeLog_ObjVersion]  DEFAULT ('0.0.0') FOR [ObjVersion]
GO
/****** Object:  DdlTrigger [trigMetaDoc_TraceDbChanges]    Script Date: 04/22/2009 13:21:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create trigger [trigMetaDoc_TraceDbChanges]
on database
for create_procedure, alter_procedure, drop_procedure,
create_table, alter_table, drop_table,
create_function, alter_function, drop_function , 
create_trigger , alter_trigger , drop_trigger 
as

set nocount on

declare @data xml
set @data = EVENTDATA()
declare @DbVersion varchar(20)
set @DbVersion =(select ga.GetDbVersion())
declare @DbType varchar(20)
set @DbType =(select ga.GetDbType())
declare @DbName varchar(256)
set @DbName [email protected]('(/EVENT_INSTANCE/DatabaseName)[1]', 'varchar(256)')
declare @EventType varchar(256)
set @EventType [email protected]('(/EVENT_INSTANCE/EventType)[1]', 'varchar(50)')
declare @ObjectName varchar(256)
set @ObjectName  = @data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'varchar(256)')
declare @ObjectType varchar(25)
set @ObjectType = @data.value('(/EVENT_INSTANCE/ObjectType)[1]', 'varchar(25)')
declare @TSQLCommand varchar(max)
set @TSQLCommand = @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'varchar(max)')
declare @opentag varchar(4)
set @opentag= '&lt;'
declare @closetag varchar(4) 
set @closetag= '&gt;'
declare @newDataTxt varchar(max) 
set @newDataTxt= cast(@data as varchar(max))
set @newDataTxt = REPLACE ( REPLACE(@newDataTxt , @opentag , '<') , @closetag , '>')
-- print @newDataTxt
declare @newDataXml xml 
set @newDataXml = CONVERT ( xml , @newDataTxt)
declare @Version varchar(50)
set @Version = @newDataXml.value('(/EVENT_INSTANCE/TSQLCommand/CommandText/Version)[1]', 'varchar(50)')

-- if we are dropping take the version from the existing object 
if  ( SUBSTRING(@EventType , 0 , 5)) = 'DROP'
set @Version =( select top 1 [Version]  from ga.tb_DataMeta_ObjChangeLog where ObjectName=@ObjectName order by [LogId] desc)



declare @LoginName varchar(256) 
set @LoginName = @data.value('(/EVENT_INSTANCE/LoginName)[1]', 'varchar(256)')
declare @FirstName varchar(50)
set @FirstName= (select [FirstName] from [ga].[tb_BLSec_LoginsForUsers] where [LoginName] = @LoginName)
declare @LastName varchar(50)
set @LastName  = (select [LastName] from [ga].[tb_BLSec_LoginsForUsers] where [LoginName] = @LoginName)
declare @SchemaName sysname 
set @SchemaName = @data.value('(/EVENT_INSTANCE/SchemaName)[1]', 'sysname');
--declare @Description xml 
--set @Description = @data.query('(/EVENT_INSTANCE/TSQLCommand/text())')




--print 'VERSION IS ' + @Version
--print @newDataTxt
--print cast(@data as varchar(max))


-- select column_name from information_schema.columns where table_name ='tb_DataMeta_ObjChangeLog'
insert into [ga].[tb_DataMeta_ObjChangeLog]
(
[DatabaseName] ,
[SchemaName],
[DbVersion] ,
[DbType],
[EventType],
[ObjectName],
[ObjectType] ,
[Version],
[SqlCommand] ,
[LoginName] ,
[FirstName],
[LastName] 
)

values(

@DbName,
@SchemaName,
@DbVersion,
@DbType,
@EventType, 
@ObjectName, 
@ObjectType , 
@Version,
@newDataTxt, 
@LoginName , 
@FirstName , 
@LastName
)
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
DISABLE TRIGGER [trigMetaDoc_TraceDbChanges] ON DATABASE
GO
/****** Object:  DdlTrigger [trigMetaDoc_TraceDbChanges]    Script Date: 04/22/2009 13:21:29 ******/
Enable Trigger [trigMetaDoc_TraceDbChanges] ON Database
GO
3
Yordan Georgiev

Nous sommes en train de déplacer toutes les bases de données vers le contrôle de source. Nous utilisons sqlcompare pour écrire un script dans la base de données (malheureusement, une édition de profession) et intégrer ce résultat dans SVN.

Le succès de votre mise en œuvre dépendra beaucoup de la culture et des pratiques de votre organisation. Les gens ici croient en la création d'une base de données par application. Il existe un ensemble commun de bases de données utilisé par la plupart des applications, ce qui entraîne de nombreuses dépendances entre bases de données (certaines sont circulaires). Il est notoirement difficile de placer les schémas de base de données dans le contrôle de source en raison des dépendances entre bases de données interdites que possèdent nos systèmes.

Je vous souhaite bonne chance, plus vous l'essayez tôt, plus vos problèmes seront rapidement résolus.

3
Min

Cela a toujours été un gros ennui pour moi aussi - il semble qu'il soit trop facile de modifier rapidement votre base de développement, de l'enregistrer (en oubliant d'enregistrer un script de modification), puis de rester bloqué. Vous pouvez annuler ce que vous venez de faire et le refaire pour créer le script de modification, ou l'écrire à partir de zéro si vous le souhaitez bien sûr, même si cela prend beaucoup de temps à l'écriture de scripts.

Un outil que j'ai utilisé dans le passé et qui a aidé à résoudre ce problème est SQL Delta. Il vous montrera les différences entre deux bases de données (serveur SQL/Oracle je crois) et générera tous les scripts de changement nécessaires à la migration de A-> B. Une autre bonne chose à faire est de montrer toutes les différences entre le contenu de la base de données entre la base de production (ou de test) et votre base de développement. Étant donné que de plus en plus d'applications et de configurations de magasin stockées sont essentielles à leur exécution dans les tables de base de données, il peut être très pénible de disposer de scripts de modification qui suppriment, ajoutent et modifient les lignes appropriées. SQL Delta affiche les lignes de la base de données exactement comme si elles étaient dans un outil de comparaison - modifiées, ajoutées, supprimées.

Un excellent outil. Voici le lien: http://www.sqldelta.com/

3
Sam Schutte

Bien que cette question apporte de nombreuses bonnes réponses, la plupart d’entre elles n’incluent pas les changements d’innovation sur le marché, en particulier les outils commerciaux.

Voici une courte liste d’outils permettant de contrôler les versions de base de données; j’ai énuméré les avantages et les inconvénients de chacun (diviseur complet: je travaille pour DBmaestro)

Red-Gate - est sur le marché depuis de nombreuses années. Il fournit un contrôle de version des objets de base de données à l'aide de scripts intégrés au contrôle de version basé sur fichier.

DBVS - fournit un contrôle de version des objets de base de données à l'aide de scripts intégrés au contrôle de version basé sur fichier.

DBmaestro - Fournit une application des processus de contrôle de version (extraction/enregistrement) sur les objets de base de données réels. Il n’est donc pas question de savoir si le référentiel de contrôle de version est synchronisé avec la base de données utilisée par l’application.

Je vous encourage à lire un compte-rendu complet et impartial des solutions de gestion du changement appliquées à la base de données par l'expert expérimenté Ben Taylor, qu'il a publié sur LinkedIn https://www.linkedin.com/Pulse/article/20140907002729-287832- résoudre-base-de-changements-gestion-avec-dbmaestro

3
Uri

J'ai utilisé l'outil dbdeploy de ThoughtWorks à l'adresse http://dbdeploy.com/ . Il encourage l'utilisation de scripts de migration. Chaque version, nous avons consolidé les scripts de modification dans un seul fichier pour en faciliter la compréhension et permettre aux administrateurs de base de données de "bénir" les modifications.

3
David Medinets

FYI Ceci a également été évoqué il y a quelques jours par Dana ... Schémas de procédures stockées/DB dans le contrôle de code source

3
Robert Paulson

RedGate est génial, nous générons de nouveaux instantanés lorsque des modifications de base de données sont effectuées (un fichier binaire minuscule) et conservons ce fichier dans les projets en tant que ressource. Chaque fois que nous devons mettre à jour la base de données, nous utilisons la boîte à outils de RedGate pour mettre à jour la base de données, tout en permettant de créer de nouvelles bases de données à partir de bases vides.

RedGate crée également des instantanés de données. Bien que je n’aie pas travaillé personnellement avec eux, ils sont tout aussi robustes.

3
Tom Anderson

Je contrôle le schéma de la base de données en scriptant tous les objets (définitions de table, index, procédures stockées, etc.). Cependant, en ce qui concerne les données elles-mêmes, vous devez simplement compter sur des sauvegardes régulières. Cela garantit que toutes les modifications structurelles sont capturées avec un historique de révision approprié, mais n'alourdit pas la base de données à chaque modification des données.

3
Ben Hoffstein

Dans notre entreprise, nous utilisons des scripts de changement de base de données. Lorsqu'un script est exécuté, son nom est stocké dans la base de données et ne s'exécutera pas à nouveau, sauf si cette ligne est supprimée. Les scripts sont nommés en fonction de la date, de l'heure et de la branche de code, ce qui permet une exécution contrôlée.

De nombreux tests sont effectués avant que les scripts ne soient exécutés dans l'environnement en direct, de sorte que des "erreurs" ne surviennent que, généralement, dans des bases de données de développement.

3
Wes P

Mon équipe versionne notre schéma de base de données sous forme de classes C # avec le reste de notre code. Nous avons un programme C # développé localement (<500 lignes de code) qui reflète les classes et crée des commandes SQL pour créer, supprimer et mettre à jour la base de données. Après avoir créé la base de données, nous exécutons sqlmetal pour générer un mappage linq, qui est ensuite compilé dans un autre projet permettant de générer des données de test. Tout cela fonctionne très bien car l'accès aux données est vérifié au moment de la compilation. Nous aimons cela parce que le schéma est stocké dans un fichier .cs qui facilite le suivi de la comparaison dans trac/svn.

2
user20620

J'ai utilisé RedGate SQL Compare Pro pour la synchronisation de schéma avec le dossier de script, puis je valide toutes mes mises à jour pour le contrôle de version. Ça marche très bien.

2
user14808

Le logiciel RedGate propose d’excellents outils qui vous aideront à mettre à jour votre base de données. Veillez à ce que vos développeurs construisent leurs propres bases de données locales isolées pour le travail de développeurs plutôt que de compter sur un "serveur de développeurs" qui peut être en panne ou non à un moment donné.

2
Karthik Hariharan

Wow, tellement de réponses. Pour la gestion des versions de base de données, vous devez contrôler le code qui modifie votre base de données. Certains CMS offrent des outils de gestion de la configuration, tels que celui dans Drupal 8. Voici un aperçu avec des étapes pratiques pour organiser votre flux de travail et vous assurer que la configuration de la base de données est versionnée , même en équipe environnements:

2
Ivan Grynenko

Je vérifie toujours mes dépôts de structure de base de données dans le contrôle de source. Des vidages de base de données complets mais je compresse et range normalement pour le stockage.

2
Adam Gibbins

Oui ... nos bases de données sont conçues dans ERwin et les DDL de chaque version sont générées automatiquement. Les fichiers ERwin sont conservés dans notre système de contrôle de code source (en fait, nos documents d'ingénierie le sont également).

2
Steve Moyer

Nous utilisons la réplication et la mise en cluster pour gérer nos bases de données, ainsi que les sauvegardes. Nous utilisons Serena pour gérer nos scripts SQL et nos implémentations de configuration. Avant de modifier la configuration, nous effectuons une sauvegarde dans le cadre du processus de gestion des modifications. Cette sauvegarde répond à notre exigence de restauration.

Je pense que tout dépend de l'échelle. Parlez-vous des applications d'entreprise qui nécessitent des sauvegardes hors site et une récupération après sinistre? Un petit groupe de travail exécutant une application comptable? Ou partout entre les deux?

2
Robert S.

J'ai commencé à travailler sur sqlHawk qui vise à fournir des outils (open source) pour résoudre ce problème.

Il en est encore à ses débuts, mais supporte déjà le stockage et l'application procédures stockées et l'exécution de mises à jour par script.

Je serais reconnaissant à toute personne ayant le temps de regarder cet outil d’apporter sa contribution.

Toutes mes excuses pour l'auto promotion flagrante, mais j'espère que cela sera utile à quelqu'un!

2
Tim Abell

Nous avons nos scripts de création/modification sous contrôle de code source. Pour ce qui est de la base de données elle-même, lorsque vous avez des centaines de tables et de nombreuses données de traitement toutes les minutes, il devient mortel pour le processeur et le disque dur de mettre à niveau toute la base de données. C'est pourquoi la sauvegarde est toujours, selon moi, le meilleur moyen de contrôler vos données.

2
David

Je suis d'accord avec de nombreuses publications concernant les migrations Ruby ActiveRecord - elles constituent un moyen élégant de gérer la base de données dans de petits fichiers incrémentiels que tout le monde peut partager. Cela dit, j'ai récemment mis en place un projet utilisant le projet de base de données de VisualStudio, et cela m'a fait un peu croire. Petite histoire - vous créez un projet de base de données, y importez tous les objets de base de données existants (le cas échéant) (tables/vues/déclencheurs/clés/utilisateurs/etc.). Cette importation donne lieu à un script "Créer" par objet. Pour gérer la base de données, modifiez le script de création puis, lors du déploiement, comparez la base de données cible à l’état de la base de données résidant dans votre projet et appliquez les instructions alter appropriées.

C'est vraiment un peu de magie et je dois admettre que c'est l'une des meilleures choses que l'équipe de VS a faite. Je suis vraiment impressionné jusqu'à présent.

Bien entendu, vous pouvez gérer l’ensemble du projet de base de données dans le système de contrôle de version de votre choix.

2
Bobby B
2
Jeff Moser

En règle générale, nous conservons tout le code de notre objet (procédures stockées, vues, déclencheurs, fonctions, etc.) dans le contrôle de code source, car ces objets sont du code et, comme pour toute autre réponse, le code appartient à une forme de contrôle de version. système.

En ce qui concerne les instructions CREATE, DROP, ALTER, etc. (DDL), nous avons mis au point et utilisons BuildMaster pour gérer le déploiement de ces scripts de manière à ce qu’ils ne puissent être exécutés qu’une seule fois contre une base de données cible ils échouent ou pas). L'idée générale est que les développeurs chargeront les scripts de changement dans le système et que, le moment venu, seuls les scripts de changement non exécutés sur la base de données de l'environnement cible seront exécutés (cette opération est gérée de manière très similaire à Réponse de l'autocratie ). La raison de cette séparation des types de script réside dans le fait qu’une fois que vous manipulez la structure d’une table, ajoutez un index, etc., vous ne pouvez en réalité pas annuler cela sans écrire un tout nouveau script ou restaurer la base de données - par opposition au code objet dans lequel vous travaillez. peut simplement supprimer une vue ou une procédure stockée, puis la recréer.

Certains avantages sont visibles lorsque, par exemple, vous restaurez votre base de données de production dans votre environnement d’intégration, le système sait automatiquement quels scripts n’ont pas été exécutés et modifiera la structure de la table de cette base de données récemment restaurée pour qu’elle soit à jour. au développement.

1
John Rasch

Je contrôle la version du script de création et j'utilise la balise svn version. Ensuite, chaque fois que j'obtiens une version qui va être utilisée, je crée un script dans un répertoire dbpatches/nommé en tant que version à transférer. Le travail de ce script consiste à modifier une base de données actuelle sans détruire les données. dbpatches /, par exemple, peut contenir des fichiers nommés 201, 220 et 240. Si la base de données est actuellement au niveau 201, appliquez le patch 220, puis le patch 240.

DROP TABLE IF EXISTS `meta`;
CREATE TABLE `meta` (
  `property` varchar(255),
  `value` varchar(255),
  PRIMARY KEY (`property`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `meta` VALUES ('version', '$Rev: 240 $');

N'oubliez pas de tester votre code avant de considérer qu'un correctif est bon. Caveat emptor!

1
Autocracy

Nous effectuons un transfert hebdomadaire de fichiers SQL dans un dépôt Subversion. C'est entièrement automatisé, mais c'est une tâche VRAIMENT lourde.

Vous voudrez limiter le nombre de révisions, car cela réduira réellement l'espace disque après un certain temps!

1
Oli

Oui bien sûr. Nous générons des sauvegardes de nos schémas PostgreSQL chaque fois qu'il y a un changement et nous les archivons. Cela nous a déjà sauvé de nombreuses fois et je ne suis à mon travail que depuis quelques mois.

0
jeffcook2150

Oui, nous contrôlons aussi nos scripts SQL avec Source. C'est une bonne pratique et vous pouvez recréer le schéma avec les données par défaut si nécessaire.

0
Guilherme Melo

J'utilise ActiveRecord Migrations. Cette gemme Ruby peut être utilisée en dehors d'un projet Rails et il existe des adaptateurs pour gérer la plupart des bases de données que vous rencontrerez. Mon conseil: si vous pouvez exécuter votre projet à partir de Postgres, vous obtenez des migrations de schéma transactionnel. Cela signifie que vous ne vous retrouverez pas avec une base de données endommagée si une migration s'applique à moitié.

0
jds

L'un des principaux cas d'utilisation de Kira est la mise à niveau de la base de données en spécifiant explicitement le schéma situé en dehors de la base de données sous forme de code. Il peut ensuite gérer la base de données et la mettre à niveau vers n’importe quelle version, peu importe la version.

0
MathGladiator

Votre équipe de projet peut avoir un administrateur de base de données à qui chaque développeur transmettrait ses instructions SQL de création, modification, insertion/mise à jour (pour les données de base). Les administrateurs de base de données exécuteraient ces requêtes et, si la mise à jour requise était effectuée avec succès, les ajoutaient à un fichier texte ou à une feuille de calcul. Chaque ajout peut être étiqueté comme un point de sauvegarde. Si vous revenez à un point de sauvegarde particulier, il vous suffit de tout supprimer et d’exécuter les requêtes jusqu’au point de sauvegarde marqué. Cette approche n’est qu’une idée ... un peu d’ajustement ici fonctionnerait pour votre environnement de développement.

0
user20358

Un gros problème, souvent négligé, est que, pour les systèmes Web plus vastes, il est nécessaire d’appliquer une période de transition ou une approche de test de compartiment pour la création de nouvelles versions. Il est donc essentiel d’avoir à la fois une restauration et un mécanisme permettant de prendre en charge l’ancien et le nouveau schéma dans la même base de données. Cela nécessite une approche d'échafaudage (rendue populiste par les gens agiles de la DB). Dans ce scénario, le manque de processus dans le contrôle de source de base de données peut être un désastre total. Vous avez besoin d'anciens scripts de schéma, de nouveaux scripts de schéma et d'un ensemble de scripts intermédiaires, ainsi que d'un rangement, une fois que le système est complètement sur la nouvelle version (ou qu'il est annulé).

Plutôt que de disposer de scripts pour recréer le schéma à partir de zéro, une approche basée sur les états est requise, dans laquelle vous avez besoin de scripts uniquement pour déplacer la base de données dans l'état souhaité, à la fois en avant et en arrière, de version à version. Votre base de données se transforme en une série de scripts d'état, qui peuvent être facilement contrôlés par une source et étiquetés avec le reste de la source.

0
Matt Jenkins

Nous maintenons des scripts DDL (et parfois DML) générés par notre outil ER (PowerAMC).

Nous avons un banc de scripts Shell qui renomment les scripts en commençant par un numéro situé sur la branche de la ligne principale. Chaque script est validé et étiqueté avec le numéro bugzilla.

Ces scripts sont alors au besoin fusionnés dans les branches de la version avec le code de l'application.

Nous avons une table enregistrant les scripts et leur statut. Chaque script est exécuté dans l’ordre et enregistré dans cette table à chaque installation par l’outil de déploiement.

0
tal

Tout code d’interface de base de données doit absolument entrer dans le contrôle de version (procédures stockées, fonctions, etc.).

Pour la structure et les données, il s'agit d'un jugement. Personnellement, je garde un modèle structurel propre de mes bases de données, mais ne les stockez pas dans le contrôle de version, en raison de leur taille. Mais le stocker dans le contrôle de version peut être très bénéfique, même pour avoir un historique.

0
pearcewg

Malheureusement, j'ai vu plus d'une équipe développer des programmes PL/SQL (procédures stockées dans Oracle) - parfois dix mille LOC - simplement en éditant le code dans TOAD (un outil de base de données), sans même enregistrer la source dans des fichiers (à l'exception de déploiement). Même si la base de données est sauvegardée régulièrement (cela ne va pas de soi, cependant), le seul moyen de récupérer une ancienne version d'une procédure stockée est de restaurer l'intégralité de la base de données, qui représente plusieurs Go. Et bien sûr, parfois, des modifications simultanées dans un fichier entraînent une perte de travail lorsque plusieurs développeurs travaillent sur le même projet.

0

J'ai entendu des gens dire que vous devez absolument conserver vos schémas dans la base de données. Je ne suis pas sûr d'être d'accord. Cela dépend vraiment du système sur lequel vous travaillez. Si votre système est relativement petit et que les données ne sont pas extrêmement importantes. Et la rapidité avec laquelle vous devez mettre en ligne un autre environnement de développement est cruciale. Dans ce cas, vous pouvez en tirer parti. Toutefois, lorsque votre schéma est inutile sans les données et que la base de données est extrêmement volumineuse, il devient pratiquement impossible de "contrôler la source" de votre base de données. Bien sûr, vous pouvez toujours conserver votre code DDL dans le contrôle de source, mais c'est essentiellement inutile. Vous ne pouvez pas obtenir les données nécessaires sans sauvegarde/restauration.

Dans le cadre d'efforts de développement de bases de données plus importants, la sauvegarde et la restauration constituent l'option de restauration préférée. Bien sûr, vous pouvez conserver les procs, vues, fonctions, etc. dans le contrôle de source, mais il n'est pas nécessaire de conserver table.sql. En outre, si votre processus de déploiement est étanche, vous ne devrez probablement jamais "restaurer" votre environnement de production.

0
sam yi

Nous insistons sur les scripts de changement et un script de définition des données principales. Ceux-ci sont archivés dans CVS avec tout autre code source. Le PL/SQL (étaient un magasin Oracle) est également contrôlé par le code source dans CVS. Les scripts de changement sont reproductibles et peuvent être transmis à tous les membres de l'équipe. Fondamentalement, juste parce que c'est une base de données, il n'y a jamais d'excuse pour ne pas la coder et utiliser un système de contrôle de source pour suivre les modifications.

0
dacracot

Pour Oracle, j'utilise Java programm Oracle-ddl2svn auto-écrit pour suivre automatiquement les modifications du schéma DDL Oracle dans SVN.

0
popalka