2010-03-10 84 views
0

我們得到了一個腳本來禁用FK約束,通過傳遞'D'來禁用激活'A'。 一旦這些被禁止,他們再次獲得幾個小時或一天後啓用回來。 可能是什麼原因?FK約束自動啓用+ SQL

腳本是如下:

CREATE PROCEDURE [dbo].[sp_DisableEnableForeignKeys] @PutFK CHAR(1) 
as 

DECLARE @IdFK integer 
DECLARE @ForeignKey sysname 
DECLARE @ChildTable sysname 
DECLARE @ParentTable sysname 
DECLARE @ParentColumn sysname 
DECLARE @ChildColumn sysname 
DECLARE @ParentColumns varchar(1000) 
    DECLARE @ChildColumns varchar(1000) 



    IF EXISTS (SELECT 1 FROM sysobjects where type = 'U' and Name ='metForeignKeys') 
     DROP TABLE metForeignKeys 


    SELECT * INTO metForeignKeys FROM 
    (
    SELECT 
     FK.constid as IdFK, 
     FK.KeyNo, 
     sofk.name as [Foreign Key Name], 
     soch.name as [Child Table], 
     scch.name as [Child Column], 
     sopa.name as [Parent Table], 
     scpa.name as [Parent Column] 
    FROM 
     sysforeignkeys FK 

    INNER JOIN sysobjects sofk on FK.constId = sofk.id 
    INNER JOIN sysobjects soch on FK.fkeyid = soch.id 
    INNER JOIN syscolumns scch on FK.fkeyid = scch.id and FK.fkey = scch.colid 
    INNER JOIN sysobjects sopa on FK.rkeyid = sopa.id 
    INNER JOIN syscolumns scpa on FK.rkeyid = scpa.id and FK.rkey = scpa.colid 
    )T 


    DECLARE met_C_Delete CURSOR FOR SELECT DISTINCT IdFK, [Child Table] FROM metForeignKeys ORDER BY [Child Table] 
    OPEN met_C_Delete 

    FETCH NEXT FROM met_C_Delete into @IdFK, @ChildTable 
    WHILE @@Fetch_Status = 0 
    BEGIN 
     SELECT @ForeignKey = [Foreign Key Name], @ChildTable = [Child Table], @ParentTable = [Parent Table] 
      FROM metForeignKeys where IdFK = @IdFK 

     IF @PutFK = 'D' 
     BEGIN 
      EXEC('ALTER TABLE [' + @ChildTable + '] with check nocheck constraint ' + @ForeignKey) 

       IF @@ERROR = 0 
        BEGIN 
         --PRINT 'Disabled FK Constraint ' + @ForeignKey + ' on table ' + @ChildTable + ' referencing '[email protected] 
         PRINT @ChildTable+' - Disabled FK Constraint ' + @ForeignKey + ' referencing '[email protected] 
        END 
       ELSE 
        BEGIN 
         PRINT 'Error disabling FK Constraint ' + @ForeignKey + ' on table ' + @ChildTable + ' referencing '[email protected] 
         --PRINT @ChildTable+' - Enabled FK Constraint ' + @ForeignKey + ' referencing '[email protected] 
        END 
       END 
     ELSE 
      BEGIN 
       EXEC('ALTER TABLE [' + @ChildTable + '] with check check constraint ' + @ForeignKey) 
       IF @@ERROR = 0 
        BEGIN 
         PRINT 'Enabled FK Constraint ' + @ForeignKey + ' on table ' + @ChildTable + ' referencing '[email protected] 
        END 
       ELSE 
        BEGIN 
         PRINT 'Error enabling FK Constraint ' + @ForeignKey + ' on table ' + @ChildTable + ' referencing '[email protected] 
        END 
      END 

     FETCH NEXT FROM met_C_Delete into @IdFK, @ChildTable 
    END 

    CLOSE met_C_Delete 
    DEALLOCATE met_C_Delete 
+0

僅供參考,有一些性能調整提示,建議不要以「sp」開頭,以系統存儲過程的名稱命名您的自定義存儲過程,並且當SQL Server遇到sp_ProcedureName時,它會提取其存儲的系統自定義之前的過程。常用命名是usp_ProcedureName。 – 2010-03-10 00:38:24

+0

問題是什麼/問題 - 你發現的外鍵被重新啓用,而無需運行您發佈的腳本? – 2010-03-10 00:38:50

+0

是的小馬,他們會重新啓用運行這個腳本 – Sreedhar 2010-03-10 00:49:03

回答

0

外鍵將無法在一個徹頭徹尾的現成的SQL Server安裝程序會自動重新啓用本身。

也許DBA擔心,開發商會忘記重新啓用限制(一個常見的問題!),並寫了作業定期重新啓用已禁用的任何約束?

如果您在跟蹤時遇到問題,可以在數據庫上定義一個DDL觸發器來記錄所有修改的時間和用戶名(ALTER_TABLE事件)。

2

「一旦你消除是不可能的,無論遺體,無論多麼不可思議,也一定是真相。」

由於限制無法啓用自己,我建議這個PROC被稱爲第二時間比「d」以外的東西。我建議在程序執行時將一些代碼記錄到表中並記錄執行過程中使用的@PutFK值。我敢打賭,你沒有預料到的是觸發執行具有除「D」以外的某個值的例程。

0

只是一個猜測:可以在SQL服務器上的潛在計劃作業(維護計劃)這樣做呢?