FK约束自动启用+ SQL

时间:2010-03-10 00:08:34

标签: sql sql-server

我们通过传递'D'取消激活'A'来激活,我们得到了一个禁用FK约束的脚本。 一旦这些被禁用,它们会在几个小时或一天后再次启用。 可能是什么原因?

脚本如下:

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 '+@ParentTable
                        PRINT @ChildTable+' - Disabled FK Constraint ' + @ForeignKey + ' referencing '+@ParentTable
                    END
                ELSE
                    BEGIN
                        PRINT 'Error disabling FK Constraint ' + @ForeignKey + ' on table ' + @ChildTable + ' referencing '+@ParentTable
                        --PRINT @ChildTable+' - Enabled FK Constraint ' + @ForeignKey + ' referencing '+@ParentTable
                    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 '+@ParentTable
                    END
                ELSE
                    BEGIN
                        PRINT 'Error enabling FK Constraint ' + @ForeignKey + ' on table ' + @ChildTable + ' referencing '+@ParentTable
                    END
            END

        FETCH NEXT FROM met_C_Delete into @IdFK, @ChildTable
    END

    CLOSE met_C_Delete
    DEALLOCATE met_C_Delete

3 个答案:

答案 0 :(得分:2)

“一旦你消除了不可能的事物,无论剩下什么,无论多么不可能,都必须是真理。”

由于约束不能自己启用,我建议使用“D”之外的其他内容来第二次调用此proc。我建议在例程中放入一些代码,在执行时记录到表中并记录执行期间使用的@PutFK值。我敢打赌,你没有预料到的事情是触发执行例程而不是“D”。

答案 1 :(得分:0)

在开箱即用的SQL Server安装中,外键不会自动重新启用。

也许DBA担心开发人员会忘记重新启用约束(一个常见问题!)并编写一份工作来定期重新启用任何禁用的约束?

如果您在跟踪此问题时遇到问题,可以在数据库上定义DDL触发器,以记录所有修改的时间和用户名(ALTER_TABLE事件)。

答案 2 :(得分:0)

只是猜测:SQL Server上的预定作业(维护计划)可能会这样做吗?