首先,您已将此标记为 Visual Studio 2012 - 如果您使用的是该版本,请务必升级到 vs 2013 或 2015 并获得最新版本的 SSDT,因为每 3 个月发布一次,其中包含新功能和修复,所以获得更新版本非常值得 - 我在下面谈到的位是当前行为,我不知道这一切是否在 Visual Studio 2012 的原始 ssdt 中可用。
有几件事要说,首先您可以通过使用 /p:BlockWhenDriftDetected 结合将数据库注册为数据层应用程序 (/p:RegisterDataTierApplication) 来强制执行有序部署。这将允许您这样做:
- 构建 dacpac 1
- 部署 dacpac 1
- 构建 dacpac 2
- 部署 dacpac 2
- 构建 dacpac 3
这会阻止您在部署 dacpac 1 之前部署 dacpac 2,但这并不理想,因为如果您在部署 dacpac 2 之前构建了 dacpac 3,那么您将无法在不重建 dacpac 3 的情况下进行部署,所以它是不理想。
当您处理数据库(任何 rdbms 而不仅仅是 sql server)的更改时,有时我们需要分阶段发布更改,对我来说,这更多是流程问题而不是技术问题。我要做的是:
- 创建变更的第一部分
- 在积压工作中创建工单以完成更改
- 部署更改
- 在部署后的未来迭代中,领取票证以完成更改
- 部署最终确定
关于此的一些注意事项:
- 确保你整理和完成工作需要纪律,以敏捷的方式工作并不意味着马虎:)
- 您编写的任何脚本都应该是幂等的,因此如果您想设置一些静态数据等,请使用诸如是否存在检查或合并语句之类的东西,如果您修改任何架构对象,则将它们包装在 if 存在等中。如果您这样做你会发现部署更简单的体验
如果您遵循此过程而不是依赖于版本控制类型的策略,那么您不必担心部署 dacpacs 的顺序,如果脚本很重要,请将其留在部署后脚本中并检查脚本是否应该在做之前做任何工作。如果您的脚本变得太大,您可以使用 :r sqlcmd 导入将它们分成不同的文件。我还听说有人使用部署存储过程并从部署后脚本调用它们。
我更喜欢只部署 dacpac 的最新(或特定版本)的过程,因为这意味着无论您是要进行较晚的构建还是回退到较早的构建,您都可以始终部署到该版本。
最后,通过添加不可为空的 fk 列的示例,可以通过 dacpac 的单个部署来做到这一点。为此,您需要:
- 创建新的表定义(包括非空和外键约束)
- 在您的部署后脚本中,对表进行更新,以便正确设置数据(显然使其具有幂等性,因此可以在需要时永久保留)
- 部署时启用 /p:GenerateSmartDefaults
生成部署脚本后,您会得到一个如下所示的脚本:
- 预部署脚本(如果有)
- 使用临时默认约束创建不为空的列
- 删除临时约束
- 使用 nocheck 创建外键,这样它实际上就不会被强制执行
- 运行部署后脚本
- 使用“with check check”启用外键约束
我提到的 /p: 参数是你传递给 sqlpackage.exe 的参数。如果您不使用它但使用其他方式进行部署,您通常可以将它们作为参数传递,如果您让我知道如果您遇到困难如何部署,我可以帮助您。有关 args 的说明,请参阅https://msdn.microsoft.com/en-us/library/hh550080.aspx(sqlpackage.exe 命令行语法)。
如果您有任何问题,请告诉我,还有一些额外的事情需要考虑,但检查您的架构定义并自动生成部署脚本会大大减少部署更改的工作,这意味着您可以专注于更有用的事情 -为其中一个编写单元测试:)。
埃德