如何防止 SSDT 发布删除列

Mag*_*ier 9 schema sql-server deployment sql-server-2008-r2 ssdt

我想创建一个发布配置文件,它可以进行完整的架构比较和发布,但不会删除在新旧版本之间删除的任何表或任何列。

我知道设置中的阻止可能的数据丢失选项。AFAIK 这会停止发布过程,以防数据丢失。所以问题是,模式升级过程会被中断(在不知何故?)还是会完成但受影响的表将被排除在外?

如果表已添加和删除列,新列是否会添加到架构中,尽管由于潜在的数据丢失而阻止数据丢失选项会停止架构更新?

编辑 09.08.2016:

我想添加这些链接以补充有关背景的其他信息的问题:

Sol*_*zky 14

这个问题分为三个部分,所以让我们从“阻止数据丢失”选项开始,删除表,然后删除列。

“阻止潜在的数据丢失”选项

如果启用“如果可能发生数据丢失,则阻止增量部署”选项:

  • 在“项目属性”的“调试”选项卡上
  • 使用/p:BlockOnPossibleDataLoss=True命令行选项
  • <BlockOnPossibleDataLoss>True</BlockOnPossibleDataLoss>在发布配置文件中指定

然后 SSDT 将为每个受影响的表编写语句,例如:

/*
The column [dbo].[Table1].[New2] is being dropped, data loss could occur.
*/
IF EXISTS (select top 1 1 from [dbo].[Table1])
    RAISERROR (N'Rows were detected. The schema update is terminating because data loss might occur.', 16, 127) WITH NOWAIT
GO

/*
Table [dbo].[DontDropMe] is being dropped.  Deployment will halt if the table contains data.
*/
IF EXISTS (select top 1 1 from [dbo].[DontDropMe])
    RAISERROR (N'Rows were detected. The schema update is terminating because data loss might occur.', 16, 127) WITH NOWAIT
GO
Run Code Online (Sandbox Code Playgroud)

这些语句在所有其他更改之前放置在增量**部署/发布脚本中。如果在任何这些表中找到任何行,这会导致发布过程完全停止。因此,在使用“数据丢失时阻止”选项时,不存在部分部署这样的事情。

** “创建”脚本总是删除并重新创建数据库,因此不会丢失任何数据;-)。

从模型中删除但仍在目标中的表

默认情况下,对象(列不是对象)不会从目标中删除。存在于目标中但在模型中缺失的对象仅在以下情况下才会被删除:

  • 在“项目属性”的“调试”选项卡上启用“DROP objects in target but not in project”选项
  • 使用/p:DropObjectsNotInSource=True命令行选项
  • <DropObjectsNotInSource>True</DropObjectsNotInSource>在发布配置文件中指定

如果您使用“删除不在源中的对象”选项但想要防止仅删除表,您可以通过以下方式排除它们:

  • 转到“高级部署设置”(“项目属性”的“调试”选项卡上的“高级...”按钮),然后转到“删除”选项卡,并启用“不删除表”选项(在可滚动列表)。
  • 使用/p:DoNotDropObjectType=Tables命令行选项
  • <DoNotDropTables>True</DoNotDropTables>在发布配置文件中指定

从模型中删除但仍在目标中的列

这个有点棘手,因为列不是对象,并且没有特定的部署选项可以忽略这种特殊情况。以下是我所能告诉你的最佳选择:

  1. 完全忽略表格。您可以通过以下方式执行此操作:

    • 转到“高级部署设置”(“项目属性”的“调试”选项卡上的“高级...”按钮),然后转到“忽略”选项卡,并启用“排除表”选项(在“排除的对象类型”可滚动列表)。
    • 使用/p:ExcludeObjectType=Tables命令行选项
    • <ExcludeTables>True</ExcludeTables>在发布配置文件中指定

    这里的缺点是不会发布新的列或新表。您仍然可以通过将部署脚本添加到项目并将它们的“构建操作”(SQL 脚本的一个属性)设置为“预部署”来自己管理这些。

  2. 创建一个“Deployment Contributor”,这是一种向SSDT API编写代码的方式,来控制DDL的生成方式

    这是一个非常灵活和强大的选择,特别是如果您的宗教信仰自我鞭打;-)。

    更新:更好的是,Ed Elliot发表了一篇博客文章,其中详细介绍了如何使用部署贡献者:SSDT 部署贡献者内部更好的是,他使用的示例就是这样做的:防止删除不在模型中的列。甚至最好的是,示例代码实际上已合并到他的 AgileSqlClub SqlPackage 部署过滤器项目中,并且该功能在以下博客文章中进行了描述:部署贡献者 KeepTableColumns 过滤器。而且,如果该功能不能完全满足您的需求,那么源代码可用,您可以进行任何您想要的更改并重新编译。

  3. 不要将 SSDT 用于架构更改。只需使用它来推送代码(存储过程、函数、触发器、SQLCLR 对象等)。您可以编写自己的架构部署脚本并将它们包含在项目中。您可以通过将它们的“构建操作”设置为“预部署”来将它们包含在部署脚本中。

  4. 文件连接建议有添加“DoNotDropColumns”或类似的东西的一个选项:-)