2014-09-24 51 views
1

最近我不得不遷移數據。爲此,我使用此命令禁用了所有約束條件在SQL Server中啓用所有可能的約束條件

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all" 

我已將所有數據從舊數據庫遷移到新數據庫。現在我面臨着一些數據衝突,不允許我重新啓用所有的約束條件。我試過這個命令,但它不適用於我

EXEC sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all" 

有沒有一種方法來啓用所有沒有數據衝突的外鍵關係? 請給我這個任務的查詢。

注意: 我有大約20個表之間有衝突的數據。我不想對它們啓用約束。 我只想在其他沒有問題的表上啓用約束(約200個表)。

+3

您需要先修復您的數據。 – 2014-09-24 13:19:48

+0

@Jeffrey Wieder請閱讀說明。 – 2014-09-24 13:36:38

回答

1

我不認爲這是可能的自動執行(但我錯了:))。 當您運行EXEC sp_msforeachtable這真的運行爲每個表seperately,意義在哪裏檢查約束將與現有數據衝突的約束不會應用(以及你從這些表出現的錯誤)

所以我的想法是執行將所有表中的所有約束都啓用一次,然後查看哪些表仍存在無法激活的約束。 (和這些表,我們將停用其他約束,以及...)

here我得到了這個漂亮的啄:

SELECT name, tbl = object_name(parent_obj) 
FROM sysobjects 
WHERE objectproperty(id, 'CnstIsDisabled') = 1 

現在,讓你被禁用所有約束和他們的表名。 在執行EXEC sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"之後,在它們上有一些約束錯誤的表應顯示在此查詢中(但可能多次,因爲可能有多個約束在同一個表上失敗)。

可以修改遠一點到

SELECT DISTINCT tbl = object_name(parent_obj), 'EXEC sp_msforeachtable "ALTER TABLE ' + object_name(parent_obj) + ' NOCHECK CONSTRAINT all"' 
FROM sysobjects 
WHERE objectproperty(id, 'CnstIsDisabled') = 1 

現在,你有最後一列可執行語句,你應該能夠只選擇最後一列的所有行和執行,那麼你應該有有效約束只有那些可以激活所有約束的表上。

0

這是不以任何方式的理想解決方案...但如果你想快速和骯髒的方式系統地去通過所有的表,並嘗試在這裏啓用約束是我應該怎樣做:

寫一個爲你做這個的程序。

運行此查詢來獲取所有表名的列表:

selectTABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' 

foreach TABLE_NAME 
{ 
    try{ 
     ALTER TABLE TABLE_NAME CHECK CONSTRAINT ALL 
    } 
    catch{} 
} 

更好的解決辦法是修復,你不能在啓用這個,只是啓用它的所有表中的數據。我會建議通過部分啓用來做到這一點。