Sql-Server

為什麼 SSDT 像 WITH NOCHECK 一樣部署內聯 FK 約束?

  • September 12, 2016

給定 SSDT 項目中 Create Table 定義的以下外鍵約束定義:

CREATE TABLE A
(...Columns...),
CONSTRAINT [FK_O] FOREIGN KEY ([OID]) REFERENCES [dbo].[O] ([ID]) ON DELETE CASCADE NOT FOR REPLICATION,
(...)

以及來自 MSDN 的以下引用

帶支票 | WITH NOCHECK 指定表中的數據是否針對新添加或重新啟用的 FOREIGN KEY 或 CHECK 約束進行驗證。如果未指定,則假定 WITH CHECK 用於新約束,而 WITH NOCHECK 假定用於重新啟用的約束。

,我想知道為什麼這個 NEW 表的 FIRST 部署結果看起來像使用如下約束 WITH NOCHECK 選項:

ALTER TABLE [dbo].[A]  WITH NOCHECK ADD CONSTRAINT [FK_O] FOREIGN KEY([OID])
REFERENCES [dbo].[O] ([ID])
ON DELETE CASCADE
NOT FOR REPLICATION 
GO

ALTER TABLE [dbo].[A] CHECK CONSTRAINT [FK_O]
GO

所以問題是,不允許定義“with Nocheck”的內聯約束定義與 MSDB 頁面中的規則配對是否會導致使用此 NEW 表上的 WITH CHECK 選項的約束?為什麼我們在這裡得到一個 WITH NOCHECK 約束?

NOT FOR REPLICATION意味著約束永遠不會被檢查,即使你明確地檢查它。

可能,SSDT 在這裡明確表達了一些隱含的東西。

只有一種外鍵約束(儘管可以信任或不信任)。

如果是新表,則兩個程式碼路徑基本相同。但他們這樣做是因為 SSDT 考慮到它可能需要調整 DDL 以添加到現有表中。

  • 如果表存在並且它使用檢查更改了表,則部署將失敗並且不會對錶施加檢查約束。
  • 如果表存在並且它使用 nocheck 更改了表,然後將檢查保留,如果舊數據不符合條件,您將收到錯誤,但至少架構更改將到位。

他們所做的是生成一組一致的程式碼*,涵蓋不存在和現有的可能性*。他們沒有嘗試針對每個案例進行優化。

本質上它沒有進一步的內在含義。這只是他們如何輸出程式碼的人工製品。

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