您是不是对数据库项目使用源代码控制? [关闭]

Posted

技术标签:

【中文标题】您是不是对数据库项目使用源代码控制? [关闭]【英文标题】:Do you use source control for your database items? [closed]您是否对数据库项目使用源代码控制? [关闭] 【发布时间】:2010-09-12 00:53:10 【问题描述】:

我觉得我的商店有漏洞,因为我们没有可靠的流程来对数据库架构更改进行版本控制。我们做了很多备份,所以我们或多或少都被覆盖了,但是以这种方式依赖你的最后一道防线是不好的做法。

令人惊讶的是,这似乎是一个共同的话题。我谈过的许多商店都忽略了这个问题,因为他们的数据库不经常更改,而且他们基本上只是试图做到一丝不苟。

但是,我知道这个故事是怎么回事。事情发生错误并丢失某些东西只是时间问题。

对此有什么最佳做法吗?有哪些对你有用的策略?

【问题讨论】:

在 Podcast 54 结束时讨论。blog.***.com/2009/05/podcast-54 【参考方案1】:

必读Get your database under version control。查看 K. Scott Allen 的系列帖子。

在版本控制方面,数据库通常是二等甚至三等公民。从我所看到的情况来看,在一百万年之内永远不会考虑编写没有版本控制的代码的团队——这是正确的——可能会以某种方式完全忘记围绕他们的应用程序所依赖的关键数据库进行版本控制的需要。我不知道当您的数据库与您的其他代码没有处于完全相同严格的源代码控制级别时,您如何称自己为软件工程师并保持正视。不要让这种情况发生在你身上。让您的数据库处于版本控制之下。

【讨论】:

我非常严格地遵循参考文章中描述的方法。您不需要实现每个级别,并且有一些变化同样可以很好地工作。该系统灵活、易于定制,允许对模式和数据更改进行细粒度控制,并且非常适合作为数据库源控制的最佳实践。可能很棘手并且增加了几乎与其余过程一样多的安全性的部分是帮助管理脚本的工具。它可以像文件串联一样简单,也可以像自动部署一样复杂。先拿到src ctrl,再想个工具。 有一个用于数据库的分布式版本控制系统Klonio,它类似于数据库的 Git/GitHub。【参考方案2】:

数据库本身?没有

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

当然,在理想情况下,您的数据库管理工具会这样做;但你只需要遵守纪律。

【讨论】:

使用 mysql Workbench,您可以在结构化文件 (xml) 中拥有所有内容,该文件可以使用 GUI 打开和处理。 xml 只是文本,是的,它可以进行版本控制,而无需键入单个 sql 语句。 数据库本身完全需要在源代码控制下,因为否则它是一个手动过程来回滚/选择性地应用架构更改以匹配您的代码库分支。如果我有三个依赖项目,并且我将它们全部切换到一个特定的分支(例如,使用一组特定的模式迁移),那么我也应该能够将我的数据库切换到该模式。同样,它应该支持合并和变基操作。这项技术严重缺乏。在数据库迁移方面,实体框架不支持多开发人员环境。 @Triynko 在实践中是行不通的。微软放弃他们的数据库项目 Visual Studio 类型 3 次以上是有原因的。这是因为知道源模式和目标模式会丢失有关模式迁移的所有信息。如果你重构你的模式,大量的信息会被吹走。我们放弃了使用该模型的尝试,转而使用经过精心设计的增量迁移脚本,可重新运行等,因此具有状态容错性。 我会注意到 Shiv 和 Tryinko 中的讨论通常被定义为“基于状态”与“基于迁移”。这是一个相当有争议的问题,两种方法都有利有弊。我会注意到,基于迁移的方法往往可以更快地使用最新迁移创建/替换/更新数据库,而基于状态的方法实际上可以创建更改。哪种方法更好,部分取决于您是优先考虑频繁的数据库更改(使用基于状态)还是频繁部署到生产/测试/本地/CI(使用基于迁移)。 至于微软为什么会使用基于状态的方法:为基于状态的方法构建工具/自动化要容易得多,而且对于开发人员来说,它更加交钥匙。目前未对其数据库使用版本控制的开发人员通常会发现基于状态的方法更具吸引力,因为它的破坏性较小。当然,破坏性较小的原因是迁移工作从开发人员推到了发布工程师……他们将生成一个差异脚本(例如,通过 SSDT)然后手动修复它,希望他们不会错过任何东西。【参考方案3】:

我非常喜欢 Rails ActiveRecord 迁移。它将 DML 抽象为 ruby​​ 脚本,然后可以轻松地在源存储库中进行版本化。

但是,只要做一些工作,您就可以做同样的事情。任何 DDL 更改(ALTER TABLE 等)都可以存储在文本文件中。为文件名保留一个编号系统(或日期戳),并按顺序应用它们。

Rails 在数据库中还有一个“版本”表,用于跟踪上次应用的迁移。您可以轻松地做到这一点。

【讨论】:

完全同意,当前迁移版本绑定到当前提交,因此您可以运行 rake 任务并通过 db 更改保持系统清洁和简单的过程【参考方案4】:

查看LiquiBase,了解如何使用源代码控制管理数据库更改。

【讨论】:

补充一点,Flyway 是一个竞争产品,提供类似的功能,在其他 *** 线程上也受到好评。【参考方案5】:

您不应该只是登录并开始输入“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

我确信有更好的方法可以做到这一点,但到目前为止它对我有用。

【讨论】:

我们做了类似的事情,只是我们将每个“if version”放在一个单独的文件中,并有一个按顺序运行文件的工具。 我们也在做类似的事情,除了 SQL 脚本与应用程序文件一起安装(新安装或升级),并记录脚本执行的位置和日期和时间。 我也写过几乎完全一样的东西,但用于 Jet(例如 MS Access)数据库。我们目前正在使用 DB Ghost for SQL Server,它可以为您完成很多工作。 您可以将begin transaction; ... end transaction; 替换为将--single-transaction 传递给psql【参考方案6】:

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

【讨论】:

【参考方案7】:

我见过的最佳实践是创建一个构建脚本来废弃和重建临时服务器上的数据库。每次迭代都有一个用于数据库更改的文件夹,所有更改都使用“Drop... Create”的脚本编写。这样,您可以通过将构建指向您想要版本的文件夹随时回滚到早期版本。

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

【讨论】:

【参考方案8】:

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

在 Ruby On Rails 中,这是由具有“迁移”的框架处理的。每当您更改数据库时,您都会创建一个脚本来应用更改并将其签入源代码管理。

我的商店非常喜欢这个想法,因此我们在基于 Java 的构建 using shell scripts 和 Ant 中添加了该功能。我们将该过程集成到我们的部署例程中。在其他不支持开箱即用的数据库版本控制的框架中编写脚本来做同样的事情是相当容易的。

【讨论】:

【参考方案9】:

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

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

db 架构被“分解”以创建很多很多小的 .sql 文件,每个描述数据库的 DDL 命令一个。

+汤姆


附加信息 2008-11-30

在过去的一年里,我一直在使用它作为开发人员,并且非常喜欢它。它可以很容易地将我的开发工作与生产进行比较,并生成一个用于发布的脚本。我不知道它是否缺少 DBA 对“企业型”项目所需的功能。

因为架构被“分解”成 sql 文件,所以源代码控制工作正常。

一个问题是,当您使用数据库项目时,您需要有不同的心态。该工具在 VS 中有一个“db 项目”,它只是 sql,加上一个自动生成的本地数据库,其中包含架构和一些其他管理数据——但没有你的应用程序数据,加上你用于的本地 dev db应用数据开发工作。你很少知道自动生成的数据库,但你必须知道它在那里,所以你可以不理会它:)。这个特殊的 db 清晰可辨,因为它的名称中有一个 Guid,

VS DB 项目很好地将其他团队成员所做的数据库更改集成到您的本地项目/关联数据库中。但是您需要采取额外的步骤将项目架构与本地开发数据库架构进行比较并应用 mods。这是有道理的,但一开始似乎很尴尬。

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

我真的很喜欢 VS DB 项目,我希望将这个工具用于我未来的所有 db 项目。

+汤姆

【讨论】:

【参考方案10】:

要求开发团队使用 SQL 数据库源代码控制管理系统并不是防止问题发生的灵丹妙药。就其本身而言,数据库源代码控制引入了额外的开销,因为开发人员需要将他们对对象所做的更改保存在单独的 SQL 脚本中,打开源代码控制系统客户端,使用客户端签入 SQL 脚本文件,然后将更改应用到实时数据库。

我可以建议使用名为 ApexSQL Source Control 的 SSMS 插件。它允许开发人员通过向导直接从 SSMS 轻松地将数据库对象与源代码控制系统映射。该插件包括对 TFS、Git、Subversion 和其他 SC 系统的支持。它还包括对源控制静态数据的支持。

下载并安装 ApexSQL Source Control 后,只需右键单击要进行版本控制的数据库,然后导航到 SSMS 中的 ApexSQL Source Control 子菜单。单击链接数据库到源代码控制选项,选择源代码控制系统和开发模型。之后,您需要为您选择的源代码控制系统提供登录信息和存储库字符串。

您可以阅读这篇文章了解更多信息:http://solutioncenter.apexsql.com/sql-source-control-reduce-database-development-time/

【讨论】:

【参考方案11】:

我通过保存创建/更新脚本和生成示例数据的脚本来做到这一点。

【讨论】:

【参考方案12】:

是的,我们通过将 SQL 作为构建的一部分来做到这一点——我们保留 DROP.sql、CREATE.sql、USERS.sql、VALUES.sql 和版本控制这些,所以我们可以恢复到任何标记的版本.

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

此外,该 SQL 会与您的源代码一起被标记。

【讨论】:

【参考方案13】:

我曾经在项目中使用过的最成功的方案是结合了备份和差异 SQL 文件。基本上,我们会在每次发布后备份我们的数据库并进行 SQL 转储,以便我们可以在需要时从头开始创建一个空白模式。然后,无论何时您需要对数据库进行更改,您都可以在版本控制下将更改脚本添加到 sql 目录。我们总是会在文件名前加上一个序列号或日期,因此第一个更改将类似于 01_add_created_on_column.sql,而下一个脚本将是 02_add_customers_index。我们的 CI 机器会检查这些并在从备份中恢复的新数据库副本上按顺序运行它们。

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

【讨论】:

【参考方案14】:

我们对所有数据库创建的对象进行源代码控制。并且为了让开发人员诚实(因为您可以创建对象而无需在源代码管理中创建对象),我们的 dbas 会定期查找不在源代码管理中的任何内容,如果他们找到任何内容,他们会放弃它而不询问是否可以。

【讨论】:

【参考方案15】:

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

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

我们的团队规则是在没有先存储设计工作的情况下,永远不要直接接触数据库服务器。但它发生了,有人可能会为了方便而试图打破规则。我们会将模式转储再次导入模式库,如果发现差异,让它做差异并抨击某人。虽然我们可以从中生成更改脚本以使我们的数据库和架构设计同步,但我们只是讨厌这样。

顺便说一句,他们还允许我们在版本控制树中创建分支,以便我可以维护一个用于暂存和一个用于生产。还有一个用于编码沙箱。

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

【讨论】:

【参考方案16】:

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

【讨论】:

【参考方案17】:

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

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

是的,在你说之前,这与 Rails 和其他人所做的非常相似,但它似乎工作得很好,所以我承认我无耻地提出了这个想法没有问题:)

【讨论】:

【参考方案18】:

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

3.- 导出 SQL ALTER 脚本 通常,您现在必须手动编写 ALTER TABLE 语句,以反映您对模型所做的更改。但您可以聪明一点,让 Workbench 为您完成繁重的工作。只需从主菜单中选择 File -> Export -> Forward Engineer SQL ALTER Script…。

这将提示您指定与当前模型进行比较的 SQL CREATE 文件。

从步骤 1 中选择 SQL CREATE 脚本。然后该工具将为您生成 ALTER TABLE 脚本,您可以针对您的数据库执行此脚本以使其更新。

您可以使用 MySQL 查询浏览器或 mysql 客户端来执行此操作。瞧!您的模型和数据库现已同步!

来源:MySQL Workbench Community Edition: Guide to Schema Synchronization

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

【讨论】:

【参考方案19】:

是的,总是。您应该能够在需要时使用一组有用的示例数据重新创建生产数据库结构。如果你不这样做,随着时间的推移,为了让事情继续运行而进行的微小更改会被遗忘,那么有一天你会被咬,大时间。它的保险您可能认为自己不需要,但当您购买它的那一天,它的价格就值了 10 倍!

【讨论】:

【参考方案20】:

关于数据库模型本身的讨论很多,但我们也将所需的数据保存在 .SQL 文件中。

例如,为了有用,您的应用程序可能需要在安装中使用:

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

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

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

【讨论】:

我们将所需的数据保存在数据库中(谁会有 thunk?),然后使用我们的工具生成这些插入/更新脚本,以使参考数据在 dev、qa、生产等之间保持同步. 以这种方式管理数据和更改要容易得多。这些脚本都由我们的版本/配置工具控制。 当您的数据库有数百万行时这是否实用?【参考方案21】:

我们对数据库周围的一切进行版本和源代码控制:

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

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

【讨论】:

【参考方案22】:

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

【讨论】:

【参考方案23】:

我通过编写所有对象(表定义、索引、存储过程等)的脚本来对数据库模式进行源代码控制。但是,就数据本身而言,只是依靠定期备份。这可确保使用适当的修订历史记录捕获所有结构更改,但不会在每次数据更改时给数据库造成负担。

【讨论】:

【参考方案24】:

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

在脚本在实时环境中运行之前进行了大量的测试,所以“oopsies”通常只发生在开发数据库上。

【讨论】:

【参考方案25】:

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

实施成功与否在很大程度上取决于贵组织的文化和做法。这里的人们相信为每个应用程序创建一个数据库。大多数应用程序都使用一组通用的数据库,这也会导致大量的数据库间依赖关系(其中一些是循环的)。由于我们的系统具有数据库间的依赖关系,将数据库模式放入源代码控制是出了名的困难。

祝您好运,越早尝试,您的问题就会越早解决。

【讨论】:

【参考方案26】:

我使用了来自 ThoughtWorks http://dbdeploy.com/ 的 dbdeploy 工具。它鼓励使用迁移脚本。在每个版本中,我们都将更改脚本合并到一个文件中,以便于理解并允许 DBA 对更改进行“祝福”。

【讨论】:

【参考方案27】:

这对我来说也一直是个大烦恼 - 似乎太容易快速更改您的开发数据库,​​保存它(忘记保存更改脚本),然后您就卡住了.您可以撤消刚刚做的事情并重做以创建更改脚本,或者如果您当然也愿意,也可以从头开始编写,尽管这会花费大量时间编写脚本。

我过去使用过的一个帮助解决这个问题的工具是 SQL Delta。它将向您展示两个数据库(我相信是 SQL 服务器/Oracle)之间的差异,并生成迁移 A-> B 所需的所有更改脚本。它所做的另一件好事是显示生产(或测试)数据库和开发数据库之间的数据库内容之间的所有差异。由于越来越多的应用程序将对其执行至关重要的配置和状态存储在数据库表中,因此拥有删除、添加和更改正确行的更改脚本可能会非常痛苦。 SQL Delta 显示数据库中的行,就像它们在 Diff 工具中一样 - 更改、添加、删除。

一个很好的工具。链接在这里: http://www.sqldelta.com/

【讨论】:

【参考方案28】:

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

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

【讨论】:

Red Gate 的 SQL 源代码控制已开发用于解决此问题,因此请查看并告诉我们它是否满足您的要求。 SQL 源代码控制高于 SQL 比较的优势在于它与 SSMS 集成,因此不需要加载单独的工具来记录不同的架构版本。 [我是 Red Gate 的产品经理]【参考方案29】:

仅供参考 这也是 Dana 几天前提出的...Stored procedures/DB schema in source control

【讨论】:

【参考方案30】:

这是一个示例穷人的解决方案,用于在 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 =@data.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'varchar(256)')
declare @EventType varchar(256)
set @EventType =@data.value('(/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

【讨论】:

以上是关于您是不是对数据库项目使用源代码控制? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

您是不是会将 NHibernate 用于具有部分无法控制的遗留数据库的项目?

有效地管理多个相同的数据库? [关闭]

您如何管理 iOS 项目中的视图标签? [关闭]

实体框架 4 代码优先的优缺点 [关闭]

从控制台应用程序记录 [关闭]

使用 Visual Studio 2010 数据库项目填充静态数据的最佳实践?