摘要:SQL - 再探停用外部索引鍵(FK)
		在 <SQL - 停用外部索引鍵(FK)> 這篇提到用語法的方式來停用與啟用外部索引鍵,可是在啟用時,會有一種情況產生,啥狀況呢!? 以下就來說說這種狀況及解決方式...
		
		環境:請參考 <SQL - 停用外部索引鍵(FK)> 這篇文章
		
		步驟一:在停用外部索引鍵前,使用UI與語法來看看
		
		UI:
		
		
		語法:
		SELECT FK.NAME, FK.KEY_INDEX_ID, FK.IS_DISABLED,
		FK.IS_NOT_FOR_REPLICATION, FK.IS_NOT_TRUSTED
		FROM SYS.FOREIGN_KEYS FK
		WHERE FK.NAME = 'FK_MY_CHILD_TABLE_MY_ROOT_TABLE'
		
		
		
		上面兩張圖各有兩個紅色框框,彼此的對應如下:
		檢查建立或重新啟用時的現有資料 = is_not_trusted
		強制使用外部索引鍵條件約束 = is_disabled
		
		步驟二:使用 T-SQL 語法停用外部索引鍵,得到的結果如下圖
		
		停用語法:ALTER TABLE dbo.MY_CHILD_TABLE NOCHECK CONSTRAINT FK_MY_CHILD_TABLE_MY_ROOT_TABLE
		
		UI:
		
		
		語法:
		SELECT FK.NAME, FK.KEY_INDEX_ID, FK.IS_DISABLED,
		FK.IS_NOT_FOR_REPLICATION, FK.IS_NOT_TRUSTED
		FROM SYS.FOREIGN_KEYS FK
		WHERE FK.NAME = 'FK_MY_CHILD_TABLE_MY_ROOT_TABLE'
		
		
		
		步驟三:使用 T-SQL 語法啟用外部索引鍵,得到的結果如下圖
		
		啟用語法:ALTER TABLE dbo.MY_CHILD_TABLE CHECK CONSTRAINT FK_MY_CHILD_TABLE_MY_ROOT_TABLE
		
		UI:
		
		
		語法:
		SELECT FK.NAME, FK.KEY_INDEX_ID, FK.IS_DISABLED,
		FK.IS_NOT_FOR_REPLICATION, FK.IS_NOT_TRUSTED
		FROM SYS.FOREIGN_KEYS FK
		WHERE FK.NAME = 'FK_MY_CHILD_TABLE_MY_ROOT_TABLE'
		
		
		
		為什麼啟用後,竟然與停用前不一樣呢!?主要原因是因為我們少了一組關鍵字「WITH CHECK」,若將 步驟三 的啟用外部索引鍵的語法改下列語法,就不會有這樣的話問題...
		
		ALTER TABLE dbo.MY_CHILD_TABLE WITH CHECK CHECK CONSTRAINT FK_MY_CHILD_TABLE_MY_ROOT_TABLE
		
		補充:MSDN的一段話
		
		WITH CHECK | WITH NOCHECK
		指定是否要依照新加入或重新啟用的 FOREIGN KEY 或 CHECK 條件約束來驗證資料表中的資料。如果未指定,則假設 WITH CHECK 為新條件約束,並假設 WITH NOCHECK 為重新啟用的條件約束。
		如果您不要依照現有的資料來確認新的 CHECK 或 FOREIGN KEY 條件約束,請使用 WITH NOCHECK。除了極少數的狀況外,我們建議您不要這麼做。在以後的所有資料更新中將會評估新條件約束。新增條件約束時,如果 WITH NOCHECK 抑制任何強制違規,當未來的更新作業更新含有不符合該條件約束的資料列時,這些強制違規可能會使這些更新作業失敗。
		查詢最佳化工具不考量定義為 WITH NOCHECK 的條件約束。這類條件約束會被忽略,直到利用 ALTER TABLE table CHECK CONSTRAINT ALL 重新啟用為止。
		
		
		OK,正題談完了,以下再來補充一個小東西
		
		Q:如何將某個資料表的外部索引鍵停用呢!? 看倌可以參考以下語法
		A:ALTER TABLE dbo.MY_CHILD_TABLE CHECK CONSTRAINT ALL
		
		參考:
		ALTER TABLE (Transact-SQL)
		停用索引的指導方針