2010-03-10 80 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服务器上的潜在计划作业(维护计划)这样做呢?