如何防止 SSDT 發布刪除列
我想創建一個發布配置文件,它可以進行完整的架構比較和發布,但不會刪除舊版本和新版本之間已刪除的任何表或任何列。
我知道設置中的 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 不是對象,並且沒有特定的部署選項可以忽略這種特殊情況。據我所知,這是您的最佳選擇:
- 完全忽略表格。您可以通過以下方式做到這一點:
- 轉到“高級部署設置”(“項目屬性”的“調試”選項卡上的“高級…”按鈕),然後轉到“忽略”選項卡,並啟用“排除表”選項(在“排除的對像類型”可滾動列表)。
- 使用
/p:ExcludeObjectType=Tables
命令行選項<ExcludeTables>True</ExcludeTables>
在發布配置文件中指定這裡的缺點是不會發布新的列或新的表。您仍然可以通過將部署腳本添加到項目並將其“建構操作”(SQL 腳本的屬性)設置為“預部署”來自己管理這些。
- 創建一個“Deployment Contributor”,這是一種將程式碼寫入 SSDT API 的方式,以控制 DDL 如何生成
- 首頁:使用建構和部署貢獻者自定義數據庫建構和部署
- 範例:演練:擴展數據庫項目部署以修改部署計劃這是一個非常靈活和強大的選擇,特別是如果你的宗教實行自我鞭笞;-)。
**更新:**更好的是,Ed Elliot發表了一篇博文,詳細介紹瞭如何使用部署貢獻者:SSDT 部署貢獻者內部。更好的是,他使用的範例就是這樣做:防止刪除不在模型中的列。甚至最好的是,範常式式碼實際上已被合併到他的 AgileSqlClub SqlPackage 部署過濾器項目中,該功能在以下部落格文章中進行了描述:部署貢獻者 KeepTableColumns 過濾器。而且,如果該功能不能完全滿足您的需求,那麼原始碼是可用的,您可以進行任何您想要的更改並重新編譯。
😺
- 不要將 SSDT 用於 Schema 更改。只需使用它來推送程式碼(儲存過程、函式、觸發器、SQLCLR 對像等)。您可以編寫自己的架構部署腳本並將它們包含在項目中。您可以通過將它們的“建構操作”設置為“預部署”來將它們包含在部署腳本中。
- 送出一個連接建議,為“DoNotDropColumns”或類似的東西添加一個選項:-)