Do you use source control for your database items?
我觉得我的商店有漏洞,因为我们没有一个可靠的过程来对数据库模式的更改进行版本控制。我们做了很多备份,所以我们或多或少会被覆盖,但是这样依赖于你的最后一道防线是不好的做法。
令人惊讶的是,这似乎是一个常见的线索。我所说的许多商店都忽略了这个问题,因为他们的数据库不经常改变,而且他们基本上只是试图一丝不苟。
不过,我知道这个故事的来龙去脉。只是时间问题,事情才会出现差错,有些事情就会消失。
这方面有什么最佳实践吗?哪些策略对您有效?
把你必须读数据库的版本控制。支票的K系列文章的城市。斯科特艾伦。
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.
《数据库的企业吗?NO
这是他们创建的脚本,包括inserts静态数据,可存储程序和类;大学课程。他们的文本文件,他们都包括在项目和检查出是在类和其他的一切。
当然在一个理想世界的数据库管理工具,你会这样做,但你真的有两个disciplined什么呢。
在绝对RAILS ActiveRecord的迁移规律。摘要信息的DML两红宝石脚本,然后可以很容易的在你的版本的源数据库。
然而,有一位的工作,你可以做同样的事。任何语言的变化(ALTER TABLE,等)可以可存储在文本文件。保持一个编号系统(或一个日期戳的文件名),和适用于它们的序列。
铁路也有一个版本的表的数据库,保持轨道的应用负载迁移。可以做的一样容易。
查看liquibase以使用源代码管理管理数据库更改。
您不应该只是登录并开始输入"alter table"命令来更改生产数据库。我所在的项目在每个客户站点上都有数据库,因此对数据库的每次更改都在两个位置进行,一个用于在新客户站点上创建新数据库的转储文件,以及一个在每次更新时运行的更新文件,该更新文件将检查当前数据库版本号与文件中的最高版本号,并更新您的数据库。SE就位。例如,最近几次更新:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | 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 |
我相信有更好的方法可以做到这一点,但到目前为止这对我来说是有效的。
对。代码就是代码。我的经验法则是,我需要能够从头开始构建和部署应用程序,而不需要查看开发或生产机器。
最好的做法已经看到冰创建脚本是一个建立在你的数据库和rebuild一登台服务器。每个迭代是给定的一个文件夹中的数据库的变化,所有的变化是与"scripted滴……"创建的。这种方式,你可以回滚之前的两个版本的任何时间的指指点点的两个城市建立文件夹,你想要两个版本。
我相信这是上帝/ CruiseControl和支配。
是的,我认为它是重要的两个版本,你的数据库。不是数据,但对某些模式。
在红宝石通铁路的手腕,这是城市的"框架"的"迁移"。任何时间你的祭坛的分贝,你让一个脚本,applies的变化和检查它到源代码控制。
我喜欢购物,这么多的想法,我们两个附加的功能性,我们建立的基于Java的脚本使用壳和蚂蚁。我们集成到我们的日常流程的部署。这将是容易的fairly写脚本做同样的事情在其他的框架,不支持数据库的版本出来的盒子。
Visual Studio中的新数据库项目提供源代码管理和更改脚本。
他们有一个比较数据库的好工具,可以生成一个脚本,将一个架构转换为另一个架构,或者更新其中一个架构中的数据以匹配另一个架构。
数据库模式被"分解"以创建许多许多小的.sql文件,每个描述数据库的DDL命令一个。
+汤姆
附加信息2008-11-30
在过去的一年里,我一直把它用作开发人员,并且非常喜欢它。它使比较我的开发人员工作和生产变得容易,并生成用于发布的脚本变得容易。我不知道DBA是否缺少"企业类型"项目所需的功能。
因为模式被"分解"到SQL文件中,所以源代码管理工作正常。
其中一个问题是,在使用DB项目时,需要有不同的思维方式。该工具在vs中有一个"db project",它只是一个SQL,加上一个自动生成的本地数据库,其中包含模式和一些其他管理数据——但没有应用程序数据,加上用于应用程序数据开发工作的本地dev db。您很少知道自动生成的数据库,但是您必须知道它在那里,这样您就可以将它单独留在那里:)。这个特殊的数据库很容易识别,因为它的名称中有一个guid,
vs-db项目很好地将其他团队成员所做的db更改集成到本地项目/关联的db中。但是您需要采取额外的步骤将项目模式与本地dev-db模式进行比较,并应用mods。这是有道理的,但一开始看起来很尴尬。
数据库项目是一个非常强大的工具。它们不仅生成脚本,而且可以立即应用它们。一定不要用它破坏生产数据库。;)
我真的很喜欢vs-db项目,我希望在以后的所有db项目中使用这个工具。
+汤姆
要求开发团队使用SQL数据库源代码管理系统并不是防止问题发生的法宝。数据库源代码管理本身就引入了额外的开销,因为开发人员需要将对对象所做的更改保存在单独的SQL脚本中,打开源代码管理系统客户端,使用客户端签入SQL脚本文件,然后将更改应用到活动数据库。
我可以建议使用名为apexsql源代码管理的ssms外接程序。它允许开发人员直接从SSMS通过向导轻松地将数据库对象映射到源代码管理系统。该插件包括对tfs、git、subversion和其他sc系统的支持。它还包括对源代码控制静态数据的支持。
下载并安装apexsql源代码管理后,只需右键单击要进行版本控制的数据库,并导航到ssms中的apexsql源代码管理子菜单。单击链接数据库到源代码管理选项,选择源代码管理系统和开发模型。之后,您需要为您选择的源代码管理系统提供登录信息和存储库字符串。
您可以阅读本文了解更多信息:http://solutioncenter.apexsql.com/sql-source-control-reduce-database-development-time/
是的,我们做的是保持我们的城市,我们的SQL作为党的建设,我们保持drop.sql,create.sql,users.sql,values.sql和版本控制这些,所以我们可以恢复任何认为后两个版本。
我们也有蚂蚁任务,可以recreate每当需要的数据库。
另外,我认为《SQL冰沿用源代码,是用的。
我市节约型创建/更新脚本,脚本和一generates数据采集。
我们对所有数据库创建的对象进行源代码控制。为了让开发人员保持诚实(因为您可以在不受源代码管理的情况下创建对象),我们的DBA会定期查找不在源代码管理中的任何对象,如果发现任何对象,他们会在不询问是否正常的情况下删除它。
我在项目中使用过的最成功的方案是将备份和差异SQL文件结合在一起。基本上,我们会在每次发布后备份数据库,并执行SQL转储,以便在需要时从头开始创建空白模式。然后,只要您需要对数据库进行更改,就可以在版本控制下向SQL目录添加一个alter scrip。我们总是在文件名前面加上序列号或日期,所以第一个更改类似于01_add_created_on_column.sql,下一个脚本是02_added_customers_index。我们的CI机器将检查这些内容,并在从备份中恢复的新数据库副本上按顺序运行它们。
我们还准备了一些脚本,开发人员可以使用单个命令将本地数据库重新初始化为当前版本。
我使用SchemaBank版本控制所有数据库架构更改:
- 从第1天开始,我将数据库模式转储导入其中。
- 我开始使用Web浏览器更改我的模式设计(因为它们是基于SaaS/云的)
- 当我想要更新我的数据库服务器时,我从它生成变更(SQL)脚本并应用到数据库。在SchemaBank中,它们要求我在生成更新脚本之前将工作作为一个版本提交。我喜欢这种练习,这样我可以随时追溯到我需要的时候。
我们的团队规则是,在没有先存储设计工作的情况下,永远不要直接接触数据库服务器。但事实上,为了方便,有些人可能会想打破规则。我们将再次将模式转储导入到SchemaBank中,并让它在发现差异时执行diff和bash操作。尽管我们可以从中生成alter脚本来同步我们的数据库和模式设计,但我们讨厌这样。
顺便说一句,他们还允许我们在版本控制树中创建分支,这样我就可以维护一个用于临时的分支和一个用于生产的分支。一个用于对沙盒进行编码。
一个非常整洁的基于Web的模式设计工具,带有版本控制和变更管理。
有两个我的一切必要的recreate分贝从裸机,负的数据本身。我在酸性有很多的方式做它,但我所有的脚本和这样的是关在仓库的颠覆和rebuild,我们可以这样的数据库结构和城市拉了颠覆一切上安装和运行方式。
我通常为我所做的每一个更改构建一个SQL脚本,另一个脚本用于恢复这些更改,并将这些脚本保持在版本控制之下。
然后,我们就有了一种方法,可以根据需要创建一个新的最新数据库,并且可以轻松地在修订之间切换。每次发布时,我们都将脚本放在一起(需要一些手工工作,但实际上很少很难),因此我们也有一组可以在版本之间转换的脚本。
是的,在你说之前,这和Rails和其他人做的事情非常相似,但它似乎工作得很好,所以我毫不犹豫地承认我无耻地提出了这个想法:)
我使用从mysql workbech导出的sql create脚本,然后使用它们的"export 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!
来源:MySQLWorkbench社区版:模式同步指南
当然,所有这些脚本都在版本控制之下。
是的,总是。您应该能够在需要时用一组有用的示例数据重新创建生产数据库结构。如果你不这样做,随着时间的推移,一些小的改变会让你忘记,然后有一天你会被咬,大的时候。它的保险,你可能认为你不需要,但你做它的一天,它的价格超过10倍!
关于数据库模型本身有很多讨论,但我们也将所需数据保存在.sql文件中。
例如,为了有用,您的应用程序在安装时可能需要:
1 2 3 4 5 | INSERT INTO Currency (CurrencyCode, CurrencyName) VALUES ('AUD', 'Australian Dollars'); INSERT INTO Currency (CurrencyCode, CurrencyName) VALUES ('USD', 'US Dollars'); |
我们将有一个名为
我相信每个数据库都应该在源代码控制下,开发人员应该有一个简单的方法从头开始创建本地数据库。受Visual Studio for Database专业人员的启发,我创建了一个开源工具,用于编写MS SQL数据库的脚本,并提供将它们部署到本地数据库引擎的简单方法。请尝试http://dbsourcetools.codeplex.com/。玩得高兴,-弥敦。
如果您的数据库是SQL Server,我们可能只有您要寻找的解决方案。SQL源代码管理1.0现已发布。
http://www.red-gate.com/products/sql_source_control/index.htm
它集成到SSMS中,并提供数据库对象和VCS之间的粘合。"脚本编写"是透明的(它在引擎盖下使用了SQL比较引擎),这应该使得它的使用非常简单,开发人员不会因此而不愿意采用该过程。
另一种Visual Studio解决方案是ReadyRoll,它作为SSDT数据库项目的子类型实现。这采用了迁移驱动的方法,更适合DevOps团队的自动化需求。
我们对数据库周围的所有内容进行版本和源代码控制:
- DDL(创建和更改)
- DML(参考数据、代码等)
- 数据模型更改(使用erwin或er/studio)
- 数据库配置更改(权限、安全对象、常规配置更改)
我们通过使用变更管理器和一些自定义脚本的自动化作业来完成所有这些工作。我们让变更管理器监控这些变更,并在完成变更后通知他们。
虽然这个问题有很多好的答案,但大多数答案不包括市场中的创新变化,特别是商业工具。
下面是一个做数据库版本控制的工具的简短列表,我列出了每种工具的优缺点(完整的披露者:我为DBMASTERO工作)
红门——上市多年。它使用与基于文件的版本控制集成的脚本提供数据库对象的版本控制。
DBV–使用与基于文件的版本控制集成的脚本提供数据库对象的版本控制。
DBMAestro–提供对真实数据库对象的版本控制过程(签出/签入)的强制执行。因此,毫无疑问,版本控制存储库是否与应用程序使用的数据库同步。
我鼓励您阅读资深数据库专家Ben Taylor关于数据库强制变更管理解决方案的全面、公正的评论,该评论发表在LinkedIn上:https://www.linkedin.com/pulse/article/2014090702729-287832-solve-database-change-management-with-dbmasetro
在源代码控制脚本的数据库架构了城市所有对象(表定义的指标,可存储程序等)。但是,作为它的数据,简单的正则rely在线备份。这是ensures全结构的变化是captured与适当的修改历史,但不负担的数据库数据每小时的变化。
在我们的业务中,我们使用数据库更改脚本。当脚本运行时,它的名称存储在数据库中,除非删除该行,否则不会再次运行。脚本是根据日期、时间和代码分支命名的,因此可以控制执行。
在脚本在实时环境中运行之前,需要进行大量的测试,因此"oopsies"通常只发生在开发数据库上。
这对我来说也一直是一个很大的烦恼-似乎对您的开发数据库进行快速更改、保存它(忘记保存更改脚本)太容易了,然后您就陷入了困境。您可以撤消刚才所做的操作,然后重做它来创建更改脚本,当然,如果您也愿意,也可以从头开始编写,尽管这是花在编写脚本上的大量时间。
我过去使用过的一个帮助实现这一点的工具是SQL Delta。它将显示两个数据库(我相信是SQL Server/Oracle)之间的差异,并生成迁移A->B所需的所有更改脚本。它所做的另一件好事是显示生产(或测试)数据库和开发数据库之间的数据库内容之间的所有差异。由于越来越多的应用程序在数据库表中存储对其执行至关重要的配置和状态,因此更改删除、添加和更改适当行的脚本可能是一件非常痛苦的事情。SQL增量显示数据库中的行,就像在diff工具中一样—更改、添加、删除。
一个很好的工具。链接如下:http://www.sqldata.com/
我们正在将所有数据库转移到源代码管理。我们正在使用sqlcompar编写数据库脚本(不幸的是,这是一个专业版功能),并将结果放入SVN。
实现的成功很大程度上取决于组织的文化和实践。这里的人们相信为每个应用程序创建一个数据库。大多数应用程序都使用一组通用的数据库,并导致大量的跨数据库依赖(其中一些是循环的)。将数据库模式放入源代码管理是众所周知的困难,因为我们的系统具有跨数据库依赖性。
祝你好运,你越早尝试,你的问题就越快得到解决。
下面是一个针对触发器的可怜人解决方案示例,该触发器实现对SQL Server 2005/2008数据库上的DB对象(通过DDL语句)的更改跟踪。我还包含一个简单的示例,说明如何在源代码中强制使用数据库上运行的每个SQL命令所需的someValue XML标记+跟踪当前的DB版本和类型(dev、test、qa、fb、prod)可以使用其他必需的属性(如等)扩展它。代码相当长——它创建了空数据库+所需的跟踪表结构+所需的db函数和填充触发器,所有这些都在[ga]模式下运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 | 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>
 </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](
 [ProducId] [int] NULL,
 [ProductName] [nchar](10) NULL,
 [ProductDescription] [varchar](5000) NULL
 ) ON [PRIMARY]
 /*
 <Version> 2.2.2 </Version>
 
 */
 </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] 
 </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](
 [ProducId] [int] NULL,
 [ProductName] [nchar](10) NULL,
 [ProductDescription] [varchar](5000) NULL
 ) ON [PRIMARY]
 /*
 <Version> 2.2.2 </Version>
 
 */
 </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= '<' declare @closetag varchar(4) set @closetag= '>' 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 |
我在http://dbdeploy.com/上使用了thoughtworks中的dbdeploy工具。它鼓励使用迁移脚本。每次发布时,我们都将更改脚本合并为一个文件,以便于理解,并允许DBA"祝福"更改。
Redgate很好,我们在数据库更改时生成新的快照(一个很小的二进制文件),并将该文件作为资源保存在项目中。每当我们需要更新数据库时,我们都使用Redgate的工具箱来更新数据库,并且能够从空数据库创建新的数据库。
Redgate还制作数据快照,虽然我没有亲自与他们合作过,但它们同样强大。
仅供参考,这也是几天前达纳提出的…源代码管理中的存储过程/db模式
我的团队将我们的数据库模式作为C类与其余代码进行了版本转换。我们有一个自行开发的C程序(<500行代码),它反映类,并创建用于构建、删除和更新数据库的SQL命令。在创建数据库之后,我们运行sqlmetal来生成一个linq映射,然后在另一个用于生成测试数据的项目中编译该映射。整个工作都很好,因为在编译时检查数据访问。我们喜欢它是因为模式存储在一个.cs文件中,这个文件很容易在trac/svn中跟踪比较。
我们使用聚类两replication和管理我们的数据库备份,为抵抗。Serena我们使用两个管理我们的SQL脚本和配置的实现等。在A构型相变冰的方式,我们perform a备份AS方的变更管理流程。这satisfies回滚备份我们的要求。
我认为这全取决于对量表。你说的是什么,企业应用需要异地备份和灾难恢复的?一个小workgroup会计运行应用程序吗?在所有的地方吗?
我同意许多关于Ruby的ActiveRecord迁移的文章-它们是一种优雅的方法,可以在每个人都可以共享的小增量文件中管理数据库。尽管如此,我最近已经使用VisualStudio的数据库项目实现了一个项目,这让我有点相信。短篇故事-创建一个数据库项目,将所有(如果有的话)现有的数据库对象导入其中(表/视图/触发器/键/用户/等等)。该导入将为每个对象生成一个"创建"脚本。要管理数据库,请更改创建脚本,然后在部署VS时将目标数据库与项目中的数据库状态进行比较,并应用适当的alter语句。
这真的有点神奇,我不得不承认,这是vs队做得更好的事情之一。我对这一点印象深刻。
当然,您可以在您选择的版本控制系统中管理整个数据库项目。
我们的创建/更改脚本在源代码管理下。至于数据库本身,当您每分钟都有数百个表和大量处理数据时,对所有数据库进行版本调整将是CPU和HDD的杀手。这就是为什么备份仍然是控制数据的最佳方法。
Redgate软件提供了一些很好的工具,可以帮助您对数据库进行版本控制。确保让您的开发人员为开发人员工作构建自己的独立本地数据库,而不是依赖一个"开发服务器",它可能在某个时间关闭,也可能不关闭。
我已经开始研究sqlhawk,它旨在提供(开源)工具来解决这个问题。
它目前处于相当早期的阶段,但已经支持存储和强制执行存储过程以及运行脚本更新。
我将感谢任何有时间查看此工具的人提供的任何信息。
为明目张胆的自我提升道歉,但我希望这对某人有用!
我已经使用RedgateSqlComparePro与脚本文件夹进行模式同步,然后将所有更新提交到版本控制。它很好用。
"短版本:将生产数据库转储到Git存储库中,以获得即时备份解决方案。"
哇,答案太多了。对于可靠的数据库版本控制,您需要版本控制更改数据库的代码。一些CMS提供配置管理工具,例如Drupal8中的配置管理工具。以下是一个概述,其中包括安排工作流程并确保数据库配置版本化的实际步骤,即使在团队环境中也是如此:
我总是检查数据库结构转储到源代码管理中。但是,完整的数据库转储通常只是压缩和存储。
是的……我们是在数据库的设计和ddls ERwin为每个版本都自动生。"欧文是在我们把文件的源代码控制系统(事实上,所以是我们工程文件)。
通常,我们将所有的对象代码(存储过程、视图、触发器、函数等)保存在源代码管理中,因为这些对象都是代码,而且这里的其他答案都一致,代码属于某种形式的版本控制系统。
至于create、drop、alter语句等(ddl),我们开发并使用buildmaster来管理这些脚本的部署,这样它们就可以针对目标数据库运行一次,也只能运行一次(不管它们是否失败)。一般的想法是,开发人员将把变更脚本上传到系统中,当需要部署时,将只运行尚未针对目标环境数据库运行的变更脚本(这与Autoracy的答案非常相似)。这种脚本类型分离的原因在于,一旦操作了表的结构、添加了索引等,就不能在不编写新脚本或还原数据库的情况下有效地撤消该操作,而不是在对象代码中删除视图或存储过程,然后重新创建它。
例如,当您将生产数据库恢复到集成环境中时,系统会自动确切地知道哪些脚本尚未运行,并将新恢复的数据库的表结构更改为与开发相关的最新版本时,可以看到一些好处。
我们有一个SQL转储到周刊回购的颠覆。它是全自动的,但它的一个很beefy任务。
你会想限制在数周的审核,因为它真的磁盘空间后一段时间!
我版本控制创建脚本,并在其中使用SVN版本标记。然后,每当我得到一个将要使用的版本时,我就在一个名为要汇总到的版本的dbpatches/目录中创建一个脚本。该脚本的任务是在不破坏数据的情况下修改当前数据库。例如,dbpatches/可能有名为201、220和240的文件。如果数据库当前处于201级,请应用补丁220,然后应用补丁240。
1 2 3 4 5 6 7 | 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 $'); |
在考虑修补程序之前不要忘记测试代码。自告奋勇!
一个经常被忽视的大问题是,对于大型的基于Web的系统,需要有一个过渡期或桶测试方法来生成新的版本。这使得在同一个数据库中同时具有回滚和支持新模式的机制变得非常重要。这需要一个脚手架方法(由敏捷数据库人员提出民粹主义)。在这种情况下,缺乏数据库源代码管理的过程可能是一场灾难。一旦系统完全处于新版本(或回滚)上,您需要旧的模式脚本、新的模式脚本和一组中间脚本,以及整理。
与其让脚本从头开始重新创建模式,还需要一种基于状态的方法,在这种方法中,您只需要脚本将数据库从一个版本移动到另一个版本所需的状态(前进和后退)。数据库变成了一系列状态脚本,可以很容易地对其进行源代码控制,并将其与其他源代码一起标记。
对于Oracle,使用自编写Java程序Oracle DDL2VSN在VPN中自动跟踪Oracle DDL方案
我听说人们说你必须将模式保存在数据库中。我不确定我是否同意。这真的取决于你所使用的系统。如果您的系统相对较小,并且数据并不十分重要。而且,将另一个开发环境联机所需的速度至关重要。那么是的…你可以从中受益。但是,如果没有数据模式是无用的,并且数据库非常大,那么实际上不可能"源代码管理"数据库。当然,您仍然可以将DDL代码保存在源代码管理中,但这基本上是无用的。没有备份/还原,无法获取所需的数据。
在更大的数据库开发工作中,我发现备份和恢复是首选的回滚选项。当然,您可以在源代码管理中保留进程、视图、函数等,但不必保留table.sql。此外,如果您的部署过程是密封的,那么您很可能永远不需要"回滚"您的生产环境。
任何数据库接口代码都必须进入版本控制(存储过程、函数等)。
对于结构和数据,这是一个判断调用。我个人在我的数据库周围保留了一个干净的结构模板,但由于其大小,不将它们存储在版本控制中。但是将它存储在版本控制中是非常有益的,即使只是有一段历史。
您的项目团队可以有一个DBA,每个开发人员都可以将其create-alter、delete、insert/update(对于主数据)SQL语句转发给它。DBA将运行这些查询,成功地进行所需的更新时,会将这些语句添加到文本文件或电子表格中。每个添加项都可以标记为保存点。如果您恢复到某个特定的保存点,只需执行一次"全部删除"操作,然后运行查询,使标记的保存点正常运行。这种方法只是一种想法…这里的一些微调对于您的开发环境很有用。
我使用ActiveRecord移植。这个RubyGem可以在Rails项目之外使用,并且有适配器来处理您遇到的大多数数据库。我的提示:如果您能够从Postgres运行您的项目,您将得到事务模式迁移。这意味着,如果迁移只应用了一半,就不会导致数据库损坏。
Kira的主要用例之一是通过显式地将数据库外部的模式指定为代码来升级数据库。然后它可以管理数据库,并从任何版本升级到任何版本。
是的,当然。每当有变化时,我们都会生成PostgreSQL模式的转储文件,并将其签入。它已经救了我们很多次了,我只工作了几个月。
我们坚持更改脚本和主数据定义脚本。这些代码与任何其他源代码一起签入到CVS中。pl/sql(以前是Oracle商店)也在cvs中受源代码控制。更改脚本是可重复的,可以传递给团队中的每个人。基本上,仅仅因为它是一个数据库,就没有理由不编写代码并使用源代码控制系统来跟踪更改。
我们维护由ER工具(poweramc)生成的DDL(有时还有DML)脚本。
我们有一个shell脚本的工作台,它从主干分支上的一个数字开始重命名脚本。每个脚本都被提交并用Bugzilla编号标记。
然后,需要将这些脚本与应用程序代码一起合并到发布分支中。
我们有一个记录脚本及其状态的表。每个脚本按顺序执行,并通过部署工具在每次安装时记录在此表中。
遗憾的是,我看到过不止一个团队在开发pl/sql程序(Oracle中的存储过程),有时是一万个loc,只需在toad(数据库工具)中编辑代码,甚至不将源文件保存到文件中(部署除外)。即使数据库定期备份(但不会想当然地认为这是理所当然的),检索存储过程旧版本的唯一方法就是还原整个数据库,这个数据库有许多GB大。当然,当多个开发人员在同一个项目上工作时,一个文件中的并发更改有时会导致工作的损失。
是的,我们也用Subversion来源代码控制我们的SQL脚本。这是一个很好的实践,您可以在需要时用默认数据重新创建模式。