我们是否对数据库项目使用源代码管理?

时间:2020-03-06 14:32:38  来源:igfitidea点击:

我觉得我的店有个漏洞,因为我们没有一个可靠的过程来对数据库架构更改进行版本控制。我们进行了大量备份,因此我们或者多或者少都得到了保障,但是以这种方式依赖最后一道防线是不明智的做法。

令人惊讶的是,这似乎是一个普通线程。我说过的许多商店都忽略了这个问题,因为它们的数据库不经常更改,并且基本上只是在尝试细致。

但是,我知道那个故事是怎么回事。事情排错了一切而丢失了只是时间问题。

是否有最佳做法?有哪些对我们有用的策略?

解决方案

数据库本身?不

创建它们的脚本,包括静态数据插入,存储过程等;当然。它们是文本文件,包含在项目中,并且像其他所有文件一样签入和签出。

当然,在理想情况下,数据库管理工具可以做到这一点。但我们只需要对此加以纪律。

我通过保存创建/更新脚本和生成样本数据的脚本来完成。

必须阅读使数据库受版本控制。查看K. Scott Allen的系列文章。

When it comes to version control, the database is often a second or even third-class citizen. From what I've seen, teams that would never think of writing code without version control in a million years-- and rightly so-- can somehow be completely oblivious to the need for version control around the critical databases their applications rely on. I don't know how you can call yourself a software engineer and maintain a straight face when your database isn't under exactly the same rigorous level of source control as the rest of your code. Don't let this happen to you. Get your database under version control.

是的...我们的数据库是在ERwin中设计的,并且会自动生成每个版本的DDL。 ERwin文件保存在我们的源代码控制系统中(实际上,我们的工程文档也是如此)。

我绝对喜欢Rails ActiveRecord迁移。它将DML抽象为ruby脚本,然后可以在源存储库中轻松对其进行版本控制。

但是,通过一些工作,我们可以做同样的事情。任何DDL更改(ALTER TABLE等)都可以存储在文本文件中。为文件名保留编号系统(或者日期戳),并依次应用它们。

Rails在数据库中还有一个"版本"表,用于跟踪上一次应用的迁移。我们可以轻松地执行相同操作。

我们每周都会将SQL转储到Subversion存储库中。它是全自动的,但这是一项非常艰巨的任务。

我们将要限制修订的数量,因为它确实会在一段时间后占用磁盘空间!

是的,我们通过将SQL保留在构建中来做到这一点-我们保留DROP.sql,CREATE.sql,USERS.sql,VALUES.sql并由版本控制这些,因此我们可以还原到任何标记的版本。

我们还有ant任务,可以在需要时重新创建数据库。

另外,SQL随同源代码一起被标记。

是的,我认为对数据库进行版本控制很重要。不是数据,而是确定的架构。

在Ruby On Rails中,这由带有"迁移"的框架来处理。每当我们更改数据库时,就可以制作一个脚本使更改生效并将其检入源代码管理。

我的商店非常喜欢这个主意,因此我们使用Shell脚本和Ant将功能添加到了基于Java的构建中。我们将流程集成到了我们的部署例程中。编写脚本以在不支持即用型数据库版本控制的其他框架中执行相同的操作将是相当容易的。

我通过编写所有对象(表定义,索引,存储过程等)的脚本来控制数据库模式。但是,对于数据本身,仅依赖常规备份。这样可以确保使用适当的修订历史记录来捕获所有结构更改,但不会在每次数据更改时都对数据库造成负担。

我见过的最佳实践是创建一个构建脚本,以在暂存服务器上剪贴和重建数据库。每次迭代都有一个用于数据库更改的文件夹,所有更改都使用" Drop ... Create"的脚本编写。通过这种方式,我们可以随时通过将构建指向要版本控制的文件夹来回滚到早期版本。

我相信这是通过NaNt / CruiseControl完成的。

我们使用复制和群集来管理数据库以及备份。我们使用Serena来管理我们的SQL脚本和配置实现。在进行配置更改之前,作为更改管理过程的一部分,我们将执行备份。此备份满足我们的回滚要求。

我认为这一切都取决于规模。我们是否在谈论需要异地备份和灾难恢复的企业应用程序?一个运行会计应用程序的小型工作组?还是介于两者之间?

我拥有从裸机重新创建数据库的一切必要功能,减去了数据本身。我敢肯定有很多方法可以做到这一点,但是我所有的脚本等等都存储在Subversion中,我们可以通过从Subversion中提取所有内容并运行安装程序来重建数据库结构。

是的。代码就是代码。我的经验法则是,我需要能够从头开始构建和部署应用程序,而无需查看开发或者生产机器。

在我们的业务中,我们使用数据库更改脚本。运行脚本时,它的名称存储在数据库中,并且不会再次运行,除非删除该行。脚本是根据日期,时间和代码分支命名的,因此可以执行受控。

在实时环境中运行脚本之前,需要进行大量测试,因此,通常情况下,"麻烦"仅发生在开发数据库上。

我在项目上使用过的最成功的方案是将备份和差异SQL文件结合在一起。基本上,我们将在每个发行版之后对数据库进行备份,并执行SQL转储,以便我们也可以从头开始创建空白模式。然后,每当需要更改数据库时,都可以在版本控制下向SQL目录中添加更改脚本。我们将始终在文件名前添加序列号或者日期,因此第一个更改将类似于01_add_created_on_column.sql,下一个脚本将为02_added_customers_index。我们的CI机器将检查这些内容,并在已从备份还原的数据库的新副本上顺序运行它们。

我们还提供了一些脚本,开发人员可以使用这些脚本通过一个命令将其本地数据库重新初始化为当前版本。

我们有在源代码管理下的创建/更改脚本。至于数据库本身,当每分钟有数百个表和大量处理数据时,对所有数据库进行版本控制将是CPU和HDD的杀手er。据我说,这就是备份仍然是控制数据的最佳方法的原因。

我们坚持使用变更单和主数据定义脚本。它们与其他任何源代码一起被检入CVS。 PL / SQL(以前是Oracle商店)也是CVS中的源代码控制。更改脚本是可重复的,并且可以传递给团队中的每个人。基本上,仅仅因为它是一个数据库,就没有任何理由不对它进行编码并使用源代码控制系统来跟踪更改。

我们永远不应仅登录并开始输入" ALTER TABLE"命令来更改生产数据库。我所在的项目在每个客户站点上都有数据库,因此对数据库的每次更改都在两个地方进行,一个用于在新客户站点上创建新数据库的转储文件,以及一个正在运行的更新文件每次更新时,都会根据文件中的最高版本检查当前数据库版本号,并就地更新数据库。因此,例如,最后几个更新:

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

我敢肯定有更好的方法可以做到这一点,但是到目前为止,它对我来说是有效的。

我通常会为所做的每个更改构建一个SQL脚本,并为每个更改构建一个SQL脚本,以还原这些更改并将这些脚本置于版本控制之下。

然后,我们可以根据需要创建一个新的最新数据库,并且可以轻松地在修订之间移动。每次发布时,我们会将脚本集中在一起(需要一些手动工作,但实际上很少有困难),因此我们还有一组可以在版本之间进行转换的脚本。

是的,在我们说出来之前,这与Rails和其他人所做的非常相似,但是看起来效果很好,所以我毫不客气地承认自己毫不客气地提出了这个想法:)

我们正在将所有数据库移至源代码管理。我们正在使用sqlcompare编写数据库脚本(不幸的是,该版本是专业版功能),并将该结果放入SVN中。

实施的成功将在很大程度上取决于组织的文化和实践。这里的人们相信为每个应用程序创建一个数据库。大多数应用程序都使用一组通用的数据库,这也会导致很多数据库间的依赖关系(其中一些是循环的)。众所周知,由于我们系统之间存在数据库间的依赖性,因此将数据库模式放入源代码管理非常困难。

祝我们好运,我们越早尝试一下,越早解决问题。

我们对所有由dabase创建的对象进行源代码控制。为了使开发人员诚实(因为我们可以创建对象而无需将它们置于Source Control中),我们的dbas会定期查找不在Source Control中的任何内容,如果发现任何内容,他们会丢弃它而不询问是否可以。

我已经使用了ThoughtWorks的dbdeploy工具,该工具位于http://dbdeploy.com/。它鼓励使用迁移脚本。在每个发行版中,我们将变更脚本整合到一个文件中,以简化理解并允许DBA"祝福"变更。

我总是检查数据库结构转储到源代码管理中。完整的数据库转储,但是我通常只是压缩并存放起来。

我对创建脚本进行版本控制,并在其中使用svn版本标签。然后,每当获得要使用的版本时,我都会在dbpatches /目录中创建一个脚本,该脚本名为要累积到的版本。该脚本的作用是在不破坏数据的情况下修改当前数据库。例如,dbpatches /可能具有名为201、220和240的文件。如果数据库当前处于级别201,则应用补丁220,然后应用补丁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 $');

在考虑补丁良好之前,请不要忘记测试代码。买者自负!

我们维护由ER工具(PowerAMC)生成的DDL(有时是DML)脚本。

我们有一系列的Shell脚本,它们以主干分支上的数字重命名这些脚本。
每个脚本均已提交,并带有bugzilla编号标记。

然后,需要在发布分支中将这些脚本与应用程序代码合并在一起。

我们有一张表格,记录了脚本及其状态。
部署工具会按顺序执行每个脚本,并在每次安装时将其记录在此表中。

我使用从MySQL Workbech导出的SQL CREATE脚本,然后使用它们的"导出SQL ALTER"功能,最终得到一系列创建脚本(当然编号)以及可以在它们之间应用更改的alter脚本。

3.- Export SQL ALTER script
  Normally you would have to write the ALTER TABLE statements by hand now, reflecting your changes you made to the model. But you can be smart and let Workbench do the hard work for you. Simply select File -> Export -> Forward Engineer SQL ALTER Script… from the main menu.
  
  This will prompt you to specify the SQL CREATE file the current model should be compared to.
  
  Select the SQL CREATE script from step 1. The tool will then generate the ALTER TABLE script for you and you can execute this script against your database to bring it up to date.
  
  You can do this using the MySQL Query Browser or the mysql client.Voila! Your model and database have now been synchronized!

来源:MySQL Workbench社区版:模式同步指南

当然,所有这些脚本都在版本控制下。

我的团队使用其余代码将数据库模式版本化为C类。我们有一个本地的Cprogram(少于500行代码),它反映了这些类并创建了SQL命令来构建,删除和更新数据库。创建数据库后,我们运行sqlmetal来生成linq映射,然后将其编译到另一个用于生成测试数据的项目中。整个过程真的很好,因为在编译时检查了数据访问。我们之所以喜欢它,是因为该模式存储在一个.cs文件中,该文件易于在trac / svn中进行比较。

签出LiquiBase以使用源代码管理来管理数据库更改。

这对我也一直是一个很大的烦恼,似乎对开发数据库进行快速更改,将其保存(忘记保存更改脚本)太容易了,然后陷入困境。我们可以撤消刚刚做的事情,然后重做以创建更改脚本,或者当然也可以从头开始编写更改脚本,尽管这花费了大量时间来编写脚本。

我过去使用过的有助于此功能的工具是SQL Delta。它将向我们显示两个数据库(我相信是SQL Server / Oracle)之间的差异,并生成迁移A-> B所需的所有更改脚本。这样做的另一个好处是,可以显示生产(或者测试)数据库与开发数据库之间的数据库内容之间的所有差异。由于越来越多的应用程序将对它们的执行至关重要的配置和状态存储在数据库表中,因此拥有删除,添加和更改适当行的更改脚本可能会非常痛苦。 SQL Delta会显示数据库中的行,就像它们在Diff工具中的外观一样(已更改,已添加,已删除)。

出色的工具。链接在这里:
http://www.sqldelta.com/

是的,总是。我们应该能够在需要时使用一组有用的样本数据来重新创建生产数据库结构。如果不这样做,随着时间的流逝,为了保持运行正常而进行的微小更改就被遗忘了,那么有一天,我们会被咬得很长。我们可能不认为需要它的保险,但是当我们这样做的时候,它的价值就值得超过10倍!

RedGate软件提供了一些很棒的工具,可以对数据库进行版本控制。确保尝试让开发人员为开发工作构建自己的隔离本地数据库,而不要依赖"开发服务器",该服务器有时可能会关闭,也可能不会关闭。

RedGate很棒,我们在进行数据库更改时会生成新的快照(一个很小的二进制文件),并将该文件作为资源保留在项目中。每当我们需要更新数据库时,我们都会使用RedGate的工具包来更新数据库,并能够从空数据库中创建新数据库。

RedGate还可以制作数据快照,虽然我还没有亲自使用过它们,但它们同样强大。

仅供参考,这也是Dana在几天前提出的...源代码控制中的存储过程/ DB模式

我已经使用RedGate SQL Compare Pro与脚本文件夹进行架构同步,然后将所有更新提交给版本控制。效果很好。

项目团队可以拥有一个DBA,每个开发人员都将向其转发其create alter,delete,insert / update(对于主数据)sql语句。 DBA将运行这些查询,并在成功进行所需的更新后将这些语句添加到文本文件或者电子表格中。每个添加项都可以标记为保存点。万一我们恢复到特定的保存点,只需删除所有文件并运行查询直到标记的保存点即可。这种方法只是一个想法...在这里进行一些微调将适合开发环境。

任何数据库接口代码绝对应进入版本控制(存储过程,函数等)。

对于结构和数据,这是一个判断调用。我个人保留数据库的干净结构模板,但由于大小原因,请勿将其存储在版本控制中。但是,即使仅具有历史记录,将其存储在版本控制中也可能非常有益。

一个经常被忽视的大问题是,对于大型的基于Web的系统,需要使用过渡期或者存储桶测试方法来发布新版本。这使得在同一数据库中同时具有回滚和支持旧模式和新模式的机制至关重要。这需要一种脚手架方法(由敏捷DB团队的平民组成)。在这种情况下,数据库源代码管理中缺乏流程可能会造成灾难。一旦系统完全安装在新版本上(或者回滚),我们就需要旧的模式脚本,新的模式脚本和一组中间脚本,并进行整理。

不需要使用脚本从头开始重新创建架构,而是需要一种基于状态的方法,在这种方法中,我们仅需要脚本即可将数据库从版本到版本向前和向后移动到所需的状态。数据库变成了一系列状态脚本,可以轻松地对其进行源代码控制并与源代码的其余部分一起进行标记。

关于数据库模型本身已经进行了很多讨论,但是我们还将所需的数据保存在.SQL文件中。

例如,为了有用,应用程序可能需要在安装中进行以下操作:

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

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

我们将在Subversion下有一个名为currency.sql的文件。作为构建过程中的手动步骤,我们将以前的currency.sql与最新的currency.sql进行比较,并编写一个升级脚本。

Visual Studio中的新数据库项目提供了源代码管理和更改脚本。

他们有一个比较数据库的好工具,可以生成一个脚本,将一个模式转换为另一个模式,或者更新一个模式中的数据以匹配另一个模式。

db模式被"切碎"以创建许多非常小的.sql文件,每个描述数据库的DDL命令都包含一个。

+汤姆

添加信息2008-11-30

在过去的一年中,我一直将其用作开发人员,并且非常喜欢它。这样可以轻松地将我的开发工作与生产进行比较,并生成用于发布的脚本。我不知道它是否缺少DBA"企业类型"项目所需的功能。

由于该架构已"切碎"到sql文件中,因此源代码控件可以正常工作。

一个陷阱是,当我们使用数据库项目时,需要有不同的心态。该工具在VS中有一个"数据库项目",它只是sql,还有一个自动生成的本地数据库,该数据库具有架构和一些其他管理数据-但没有应用程序数据,还有用于应用程序的本地dev db数据开发工作。我们很少知道自动生成的数据库,但是我们必须在那里知道它,因此我们可以不理会它:)。可以清楚地识别出这个特殊的数据库,因为它的名称中有一个Guid,

VS DB项目在将其他团队成员所做的数据库更改集成到本地项目/相关数据库中方面做得很好。但是我们需要采取额外的步骤,才能将项目架构与本地dev db架构进行比较并应用mod。这是有道理的,但起初似乎很尴尬。

数据库项目是一个非常强大的工具。它们不仅生成脚本,而且可以立即应用它们。确保不要破坏它的生产数据库。 ;)

我真的很喜欢VS DB项目,并且我希望以后的所有数据库项目都可以使用此工具。

+汤姆

这是一个穷人解决方案的示例,该解决方案用于在SQL Server 2005/2008数据库上实现对db对象(通过DDL声明)的更改进行跟踪的触发器。我还包含一个简单示例,说明如何强制在数据库中运行的每个sql命令的源代码中强制使用必需的someValue xml标记,以及跟踪当前数据库的版本和类型(dev,test,qa,fb,prod )
可以使用其他必需属性(例如)扩展它。
该代码相当长,它创建了一个空数据库+所需的跟踪表结构+所需的db函数以及填充触发器,它们均在[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

是的当然。每当发生更改时,我们都会生成PostgreSQL模式的转储并将其检入。它已经为我们节省了很多时间,而我只工作了几个月。

我们对数据库周围的所有内容进行版本控制和源代码控制:

  • DDL(创建和更改)
  • DML(参考数据,代码等)
  • 数据模型更改(使用ERwin或者ER / Studio)
  • 数据库配置更改(权限,安全对象,常规配置更改)

我们使用变更管理器和一些自定义脚本通过自动化作业来完成所有这些工作。我们让变更管理器监视这些变更并通知完成的时间。

我使用SchemaBank对所有数据库架构更改进行版本控制:

  • 从第一天开始,我将数据库模式转储导入到其中
  • 我开始使用Web浏览器更改架构设计(因为它们是基于SaaS /基于云的)
  • 当我想更新数据库服务器时,我从中生成更改(SQL)脚本并将其应用于数据库。在Schemabank中,他们要求我在生成更新脚本之前将我的工作提交为一个版本。我喜欢这种练习,这样我就可以在需要时随时进行追溯。

我们的团队规则是永远不要直接触摸数据库服务器,而无需先存储设计工作。但是它的确发生了,为了方便起见,有人可能会想违反规则。我们将再次将架构转储导入到schemabank中,让它进行比较,如果发现差异,则对某人进行打击。尽管我们可以从中生成alter scripts,以使我们的数据库和架构设计同步,但我们对此感到讨厌。

顺便说一句,它们还允许我们在版本控制树中创建分支,以便我可以维护一个用于登台,一个用于生产。以及一个用于编码沙箱的代码。

一个非常简洁的基于Web的架构设计工具,具有版本控制和变更管理功能。

可悲的是,我看到多个团队仅通过在TOAD(一种数据库工具)中编辑代码,甚至没有将源保存到文件中(部署除外)来开发PL / SQL程序(Oracle中的存储过程),有时甚至一万个LOC。 。即使定期备份数据库(尽管这也不是理所当然的),但检索存储过程的旧版本的唯一方法是还原整个数据库,该数据库大小很多GB。当然,当多个开发人员在同一个项目上工作时,有时一个文件中的并发更改会导致工作丢失。

"简短版本:将生产数据库转储到git存储库中,以提供即时备份解决方案。"

我相信每个数据库都应该受到源代码控制,并且开发人员应该有一种简便的方法来从头开始创建本地数据库。受Visual Studio for Database Professionals的启发,我创建了一个开放源代码工具,该工具可对MS SQL数据库进行脚本编写,并提供将它们部署到本地DB引擎的简便方法。尝试http://dbsourcetools.codeplex.com/。玩得开心,
内森

我使用ActiveRecord迁移。这个Ruby宝石可以在Rails项目之外使用,并且有适配器来处理我们将遇到的大多数数据库。我的提示:如果能够在Postgres上运行项目,则可以进行事务性模式迁移。这意味着,如果仅进行一半迁移,则不会导致数据库损坏。

Kira的主要用例之一是通过将数据库外部的架构明确指定为代码来进行数据库升级。然后,它可以管理数据库并将其从任何版本升级到任何版本。

是的,我们也通过subversion源代码控制我们的sql脚本。这是一个好习惯,我们可以在需要时使用默认数据重新创建架构。

如果数据库是SQL Server,我们可能只是我们要寻找的解决方案。 SQL Source Control 1.0现在已经发布。

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

这集成到SSMS中,并提供了数据库对象和VCS之间的粘合。 "脚本输出"是透明进行的(它在后台使用了SQL Compare引擎),这应该使其使用起来如此简单,以至于不会妨碍开发人员采用该过程。

另一种Visual Studio解决方案是ReadyRoll,它作为SSDT数据库项目的子类型实现。这采用了迁移驱动的方法,该方法更适合DevOps团队的自动化要求。