SSDT创建回滚部署脚本?

3
我们可以使用TFS&SSDT创建SQLServer部署脚本,但是否有一种方法可以创建回滚脚本,以便我们可以回滚部署?
谢谢
2个回答

7
由于SSDT(和类似的产品)都是通过将项目中的模式与实时数据库进行比较以将数据库与模型同步,因此没有直接创建回滚脚本的方法。还需要考虑通过预或后部署脚本更改/添加/删除的数据。
话虽如此,有几个选择:
1.每次发布时拍摄快照。您可以使用上一个版本的快照来进行回滚比较。
2.在其他地方维护先前的版本-可能从生产系统对您的本地机器进行模式比较。您可以使用它与生产环境进行比较并进行回滚。
3.在发布之前生成现有系统的dacpac(使用SQLPackage或SSDT)。如果出现问题,您可以使用它将该模式版本部署回数据库。
4.在发布之前拍摄数据库快照。最好的情况是,您不需要它并且可以删除快照。最坏的情况下,您可以使用它进行回滚。当然,您需要注意空间和IO,因为您将在其他地方维护该原始状态。
5.通过多个环境运行更改以最小化回滚的需求。理想情况下,如果您已经在开发、QA和暂存/用户接受环境中运行了此代码和发布,则您的代码和发布应足够稳定,可以在没有任何问题的情况下发布。
您需要相应地编写代码以回滚数据更改。这可能有点棘手,因为每种情况都不同。您需要确保编写一个脚本,可以撤消发布的任何更改。如果插入了一行,则需要回滚脚本将其删除。如果更新了大量数据,则需要备份该数据或其他方法将其恢复。

你也可以从源代码控制中“发布”以前的版本。因为你正在使用源代码控制,对吧? - Mark Sowul
1
@MarkSowul:这不一样,对吧?如果我在两个版本之间更改了单个列,如果源代码控制存储完整的数据库模式,那么有没有一种简单的方法可以回滚到以前的版本,而不必删除生产数据库中的所有数据库对象?我还没有使用SSDT,所以我只是想知道是否可能。 - Tim Schmelter
假设您的DB(和SSDT)版本为1.0,其中有一个具有三个列的表:Id INT,Name VARCHAR(10)。然后在2.0中,您将其更改为Id BIGINT,Name VARCHAR(10),Description VARCHAR(1000)。 SSDT当然会更改Id列的类型,并添加Description列。如果您现在尝试重新发布版本1模式,则SSDT将删除Description并将Id更改回INT。 SSDT部署表示“这就是我想要数据库看起来的样子”,SSDT只会进行必要的更改以使模式看起来像那样。以前的版本仍然只是不同的目标模式。 - Mark Sowul
1
SSDT将尝试进行架构更改,但是在您的示例中ID为BIGINT,如果有人利用此特性输入值大于INT可以处理的值,则可能会遇到问题。回滚需要处理的内容会稍微多一点,因为它涉及到数据库中的数据而不仅仅是架构。您真的想丢失该新列中输入的数据吗?那个修复重要错误的proc呢?也许需要进行热修复?这绝对是一个需要仔细计划和理解回滚原因的领域。 - Peter Schott
没错,我并不是说这是一个完全安全的回滚方法;只是它是与选项(1)、(2)和(3)同级的。如果您正在使用源代码控制,您不一定需要采取 SSDT 快照或 dacpacs;这相当于重新发布旧版本的 SSDT 项目。 - Mark Sowul
顺带一提,我认为你也可以使用一个包含数据的 bacpac 文件。那更接近于 (4) 。当然,这并不处理部署后用户随后添加/修改的数据。 - Mark Sowul

1
在对数据库项目进行任何更改之前,我会拍摄一个快照(dacpac),以便将修改后的数据库项目与其进行比较,以生成发布脚本。虽然很容易交换源和目标来执行反向模式比较,但我发现它不允许我从反向比较中生成更新脚本(这将是回滚脚本),可能是因为目标是数据库项目。
为了解决这个问题并生成回滚脚本,我会执行以下步骤:
1. 将修改后的数据库项目部署到我的(localdb)开发数据库; 2. 从源代码控制中检出之前未进行更改的数据库项目的先前版本; 3. 从数据库项目的先前版本运行模式比较到(localdb)开发数据库; 4. 使用模式比较生成更新脚本。此更新脚本将是回滚脚本。
虽然直接生成回滚脚本会更好,但上述四个步骤不到五分钟即可完成。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接