Sql-Server
為什麼 SSDT 像 WITH NOCHECK 一樣部署內聯 FK 約束?
給定 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 更改了表,然後將檢查保留,如果舊數據不符合條件,您將收到錯誤,但至少架構更改將到位。
他們所做的是生成一組一致的程式碼*,涵蓋不存在和現有的可能性*。他們沒有嘗試針對每個案例進行優化。
本質上它沒有進一步的內在含義。這只是他們如何輸出程式碼的人工製品。