Sql-Server

如何防止 SSDT 發布刪除列

  • August 9, 2016

我想創建一個發布配置文件,它可以進行完整的架構比較和發布,但不會刪除舊版本和新版本之間已刪除的任何表或任何列。

我知道設置中的 BLOCK 可能的數據失去選項。AFAIK 這將停止發布過程,以防 DATA 失去。所以問題是,模式升級過程會被中斷(在茫茫人海中?)還是會完成但受影響的表會被排除在外?

如果表已添加和刪除列,是否會將新列添加到架構中,儘管阻止數據失去選項會因為潛在的數據失去而停止架構更新?

編輯 09.08.2016:

我想添加這些連結以補充有關背景的其他資訊的問題:

這個問題分為三個部分,所以讓我們從“Block on Data Loss”選項開始,刪除表,然後刪除列。

“阻止潛在的數據失去”選項

如果啟用“在可能發生數據失去時阻止增量部署”選項:

  • 在“項目屬性”的“調試”選項卡上
  • 使用/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

這些語句在所有其他更改之前放置到增量**部署/發布腳本中。如果在任何這些表中找到任何行,這將導致發布過程完全停止。因此,在使用“數據失去阻止”選項時,不存在部分部署之類的事情。

** “創建”腳本始終刪除並重新創建數據庫,因此不會失去任何數據;-)。

從模型中刪除但仍在目標中的表

預設情況下,不會從目標中刪除對象(並且列不是對象)。只有在以下情況下才會刪除目標中存在但模型中缺失的對象:

  • 在“項目屬性”的“調試”選項卡上啟用“在目標中但不在項目中放置對象”選項
  • 使用/p:DropObjectsNotInSource=True命令行選項
  • <DropObjectsNotInSource>True</DropObjectsNotInSource>在發布配置文件中指定

如果您使用“Drop Objects not in Source”選項但想防止僅刪除表,您可以通過以下方式排除它們:

  • 轉到“高級部署設置”(“項目屬性”的“調試”選項卡上的“高級…”按鈕),然後轉到“刪除”選項卡,並啟用“不刪除表”選項(在可滾動列表)。
  • 使用/p:DoNotDropObjectType=Tables命令行選項
  • <DoNotDropTables>True</DoNotDropTables>在發布配置文件中指定

從模型中刪除但仍在目標中的列

這個有點棘手,因為 Columns 不是對象,並且沒有特定的部署選項可以忽略這種特殊情況。據我所知,這是您的最佳選擇:

  1. 完全忽略表格。您可以通過以下方式做到這一點:
  • 轉到“高級部署設置”(“項目屬性”的“調試”選項卡上的“高級…”按鈕),然後轉到“忽略”選項卡,並啟用“排除表”選項(在“排除的對像類型”可滾動列表)。
  • 使用/p:ExcludeObjectType=Tables命令行選項
  • <ExcludeTables>True</ExcludeTables>在發布配置文件中指定這裡的缺點是不會發布新的列或新的表。您仍然可以通過將部署腳本添加到項目並將其“建構操作”(SQL 腳本的屬性)設置為“預部署”來自己管理這些。
  1. 創建一個“Deployment Contributor”,這是一種將程式碼寫入 SSDT API 的方式,以控制 DDL 如何生成

**更新:**更好的是,Ed Elliot發表了一篇博文,詳細介紹瞭如何使用部署貢獻者:SSDT 部署貢獻者內部更好的是,他使用的範例就是這樣做:防止刪除不在模型中的列。甚至最好的是,範常式式碼實際上已被合併到他的 AgileSqlClub SqlPackage 部署過濾器項目中,該功能在以下部落格文章中進行了描述:部署貢獻者 KeepTableColumns 過濾器。而且,如果該功能不能完全滿足您的需求,那麼原始碼是可用的,您可以進行任何您想要的更改並重新編譯。

😺

  1. 不要將 SSDT 用於 Schema 更改。只需使用它來推送程式碼(儲存過程、函式、觸發器、SQLCLR 對像等)。您可以編寫自己的架構部署腳本並將它們包含在項目中。您可以通過將它們的“建構操作”設置為“預部署”來將它們包含在部署腳本中。
  2. 送出一個連接建議,為“DoNotDropColumns”或類似的東西添加一個選項:-)

引用自:https://dba.stackexchange.com/questions/139478