Sql-Server
ALTER TABLE CHECK CONSTRAINT 是多餘的嗎?
我創建了一個帶有外鍵約束的表。當我通過 SSMS 生成表創建腳本時,它會創建以下程式碼:
ALTER TABLE [dbo].[MainTable] WITH CHECK ADD CONSTRAINT [FK_MainTable_ForeignKeyTable] FOREIGN KEY([FK_Field]) REFERENCES [dbo].[ForeignKeyTable] ([PK_Field]) GO ALTER TABLE [dbo].[MainTable] CHECK CONSTRAINT [FK_MainTable_ForeignKeyTable] GO
由於第一條語句創建了 WITH CHECK 約束,這是否會使第二條語句變得多餘?如果不是,那麼 CHECK CONSTRAINT 完成了什麼,而 WITH CHECK 沒有完成?
我看到了ALTER TABLE CHECK CONSTRAINT,但在這種情況下,SSMS 正在生成第一個帶有 NOCHECK 的語句,因此同時擁有這兩個語句是有意義的。
第一條語句更改表以添加約束。第二條語句啟用或禁用將來插入或更新的約束。
因此,
ALTER TABLE ... CHECK CONSTRAINT ...
為將來的插入/更新啟用約束。如果指定ALTER TABLE ... NOCHECK CONSTRAINT ...
,則禁用約束,從而允許將來的插入和更新成功,即使外鍵引用的表中的列不包含匹配值。通過此範例,您可以看到同時存在這兩個語句的實用性:USE tempdb; IF OBJECT_ID(N'dbo.b', N'U') IS NOT NULL DROP TABLE dbo.b; IF OBJECT_ID(N'dbo.a', N'U') IS NOT NULL DROP TABLE dbo.a; CREATE TABLE dbo.a ( a_ID int NOT NULL CONSTRAINT a_primary_key PRIMARY KEY CLUSTERED , SomeData varchar(10) NOT NULL ) ON [PRIMARY]; INSERT INTO dbo.a (a_ID, SomeData) VALUES (1, 'aaaa') , (2, 'bbbb') , (3, 'cccc'); CREATE TABLE dbo.b ( b_ID int NOT NULL CONSTRAINT b_primary_key PRIMARY KEY CLUSTERED , SomeData varchar(10) NOT NULL , a_ID int NOT NULL ) ON [PRIMARY]; INSERT INTO dbo.b (b_ID, SomeData, a_ID) VALUES (49, 'dddd', 1) , (50, 'eeee', 2) , (51, 'ffff', 3);
因此,我們創建了兩個沒有定義關係的表。後來,我們決定要設計關係,所以我們添加一個外鍵
dbo.b
來引用dbo.a
. 我們希望檢查現有行的有效性,但不關心將來可能添加的新行1。ALTER TABLE dbo.b WITH CHECK ADD CONSTRAINT b_a_foreign_key FOREIGN KEY (a_ID) REFERENCES a(a_ID); ALTER TABLE dbo.b NOCHECK CONSTRAINT b_a_foreign_key;
都好。現有行已驗證,新行不會針對外鍵進行驗證:
INSERT INTO dbo.b (b_ID, SomeData, a_ID) VALUES (52, 'gggg', 4);
表格內容:
SELECT * FROM dbo.b LEFT JOIN dbo.a ON b.a_ID = a.a_ID
結果:
╔══════╦══════════╦══════╦══════╦══════════╗ ║ b_ID ║ SomeData ║ a_ID ║ a_ID ║ SomeData ║ ╠══════╬══════════╬══════╬══════╬══════════╣ ║ 49 ║ dddd ║ 1 ║ 1 ║ aaaa ║ ║ 50 ║ eeee ║ 2 ║ 2 ║ bbbb ║ ║ 51 ║ ffff ║ 3 ║ 3 ║ cccc ║ ║ 52 ║ gggg ║ 4 ║ NULL ║ NULL ║ <--瘋狂的東西 ╚══════╩══════════╩══════╩══════╩══════════╝
因此,由於在 SSMS 中編寫表格的程式碼必須涵蓋所有可能發生的情況,因此
ALTER TABLE ... CHECK CONSTRAINT ...
即使不需要,它也會輸出 a,並且在絕大多數情況下肯定不需要。1 - 為什麼有人希望驗證現有行,但不關心新行有點神秘,但你去吧。