2013-12-09 76 views
1

我有一個OLTP和一個OLAP數據庫,我們在OLAP中保持一個滾動的13個月的數據。幾個ETL作業使得夜間作業保持最新狀態,並且在執行ETL時,沒有任何作業會禁用外鍵。偶爾,由於我還沒有發現的原因,我的一些OLTP外鍵變得不可信。我使用下面的腳本(感謝Brent Ozar的小組)來識別並修復這些鍵。什麼是可以使外鍵變爲不可信的一些場景

我的問題是:除了手動禁用然後忘記重新啓用密鑰,什麼情況會導致外鍵變得不可信?我已經搜遍了我們的ETL工作,沒有什麼突破。

腳本識別,然後修復不可信鍵:

識別不可信的鑰匙

下面的腳本,布倫特奧扎爾組的讚揚,將有助於識別不可信鍵。請注意,此腳本必須在連接到您希望檢查的給定數據庫時運行。

SELECT '[' + s.name + '].[' + o.name + '].[' + i.name + ']' AS keyname 
from sys.foreign_keys i 
INNER JOIN sys.objects o ON i.parent_object_id = o.object_id 
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id 
WHERE i.is_not_trusted = 1 AND i.is_not_for_replication = 0 

SELECT '[' + s.name + '].[' + o.name + '].[' + i.name + ']' AS keyname 
from sys.check_constraints i 
INNER JOIN sys.objects o ON i.parent_object_id = o.object_id 
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id 
WHERE i.is_not_trusted = 1 AND i.is_not_for_replication = 0 AND i.is_disabled = 0 

修復不可信鍵

一旦你已經確定不信任的鑰匙,使用下面的腳本來重新啓用它們:

WITH CHECK CHECK約束ALTER TABLE MyTableName MyConstraintName

大表需要時間,所以這應該在維護窗口期間執行。由於鍵被禁用,您可能會發現不符合約束規則的鍵值。這些值需要被編輯或刪除行以成功重新啓用密鑰。

ALTER TABLE腳本用於PriceGuide和PriceGuideDW

我已經做了一些修改,以布倫特奧扎爾腳本專門爲我們的數據庫。這些腳本會生成必要的ALTER TABLE腳本來修復不可信鍵:

Use PriceGuide 
Go 
SELECT 'ALTER TABLE [' + o.name + '] WITH CHECK CHECK CONSTRAINT ' + 
--'[' + s.name + '].[' + o.name + ']. 
+ '[' + i.name + '];' AS keyname 
from sys.foreign_keys i 
INNER JOIN sys.objects o ON i.parent_object_id = o.object_id 
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id 
WHERE i.is_not_trusted = 1 AND i.is_not_for_replication = 0 

SELECT 'ALTER TABLE [' + o.name + '] WITH CHECK CHECK CONSTRAINT ' + 
--'[' + s.name + '].[' + o.name + ']. 
+ '[' + i.name + '];' AS keyname 
from sys.check_constraints i 
INNER JOIN sys.objects o ON i.parent_object_id = o.object_id 
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id 
WHERE i.is_not_trusted = 1 AND i.is_not_for_replication = 0 AND i.is_disabled = 0 

Use PriceGuideDW 
Go 
SELECT 'ALTER TABLE [' + o.name + '] WITH CHECK CHECK CONSTRAINT ' + 
--'[' + s.name + '].[' + o.name + ']. 
+ '[' + i.name + '];' AS keyname 
from sys.foreign_keys i 
INNER JOIN sys.objects o ON i.parent_object_id = o.object_id 
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id 
WHERE i.is_not_trusted = 1 AND i.is_not_for_replication = 0 

SELECT 'ALTER TABLE [' + o.name + '] WITH CHECK CHECK CONSTRAINT ' + 
--'[' + s.name + '].[' + o.name + ']. 
+ '[' + i.name + '];' AS keyname 
from sys.check_constraints i 
INNER JOIN sys.objects o ON i.parent_object_id = o.object_id 
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id 
WHERE i.is_not_trusted = 1 AND i.is_not_for_replication = 0 AND i.is_disabled = 0 
+0

是否可以修改此腳本以刪除未使用的外鍵? –

+0

所以你想刪除不信任的外鍵?如果是這樣,請使用第一個腳本來標識對象(表和外鍵),然後構建一個如下所示的腳本:alter table

drop <外鍵名稱> – bsivel

+0

有沒有這兩種腳本可以結合的方式?在數據庫中搜索已禁用/不可信的FK並在遇到它們時放下它們? –

回答

1

好了,加入外鍵WITH NOCHECK肯定的是,想到的第一種方式。

+0

同意但是我看到的是使用CHECK創建的鍵,它似乎在一段時間內(一次數月)強制引用完整性,但隨後以某種方式變爲不可信。 – bsivel

+0

然後有人必須禁用它們,可能會對引用的表進行一些更改...想不到任何其他方式他們可以變得不信任。 –

相關問題