How do I drop a foreign key constraint only if it exists in sql server?

前端 未结 11 1593
礼貌的吻别
礼貌的吻别 2020-12-04 05:34

I can drop a table if it exists using the following code but do not know how to do the same with a constraint:

IF EXISTS(SELECT 1 FROM sys.objects WHERE OBJE         


        
相关标签:
11条回答
  • 2020-12-04 05:50

    James's answer works just fine if you know the name of the actual constraint. The tricky thing is that in legacy and other real world scenarios you may not know what the constraint is called.

    If this is the case you risk creating duplicate constraints, to avoid you can use:

    create function fnGetForeignKeyName
    (
        @ParentTableName nvarchar(255), 
        @ParentColumnName nvarchar(255),
        @ReferencedTableName nvarchar(255),
        @ReferencedColumnName nvarchar(255)
    )
    returns nvarchar(255)
    as
    begin 
        declare @name nvarchar(255)
    
        select @name = fk.name  from sys.foreign_key_columns fc
        join sys.columns pc on pc.column_id = parent_column_id and parent_object_id = pc.object_id
        join sys.columns rc on rc.column_id = referenced_column_id and referenced_object_id = rc.object_id 
        join sys.objects po on po.object_id = pc.object_id
        join sys.objects ro on ro.object_id = rc.object_id 
        join sys.foreign_keys fk on fk.object_id = fc.constraint_object_id
        where 
            po.object_id = object_id(@ParentTableName) and 
            ro.object_id = object_id(@ReferencedTableName) and
            pc.name = @ParentColumnName and 
            rc.name = @ReferencedColumnName
    
        return @name
    end
    
    go
    
    declare @name nvarchar(255)
    declare @sql nvarchar(4000)
    -- hunt for the constraint name on 'Badges.BadgeReasonTypeId' table refs the 'BadgeReasonTypes.Id'
    select @name = dbo.fnGetForeignKeyName('dbo.Badges', 'BadgeReasonTypeId', 'dbo.BadgeReasonTypes', 'Id')
    -- if we find it, the name will not be null
    if @name is not null 
    begin 
        set @sql = 'alter table Badges drop constraint ' + replace(@name,']', ']]')
        exec (@sql)
    end
    
    0 讨论(0)
  • 2020-12-04 05:56

    The accepted answer on this question doesn't seem to work for me. I achieved the same thing with a slightly different method:

    IF (select object_id from sys.foreign_keys where [name] = 'FK_TableName_TableName2') IS NOT NULL
    BEGIN
        ALTER TABLE dbo.TableName DROP CONSTRAINT FK_TableName_TableName2
    END
    
    0 讨论(0)
  • 2020-12-04 05:59

    The more simple solution is provided in Eric Isaacs's answer. However, it will find constraints on any table. If you want to target a foreign key constraint on a specific table, use this:

    IF EXISTS (SELECT * 
      FROM sys.foreign_keys 
       WHERE object_id = OBJECT_ID(N'dbo.FK_TableName_TableName2')
       AND parent_object_id = OBJECT_ID(N'dbo.TableName')
    )
      ALTER TABLE [dbo.TableName] DROP CONSTRAINT [FK_TableName_TableName2]
    
    0 讨论(0)
  • 2020-12-04 06:03
    Declare @FKeyRemoveQuery NVarchar(max)
    
    IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.TableName'))
    
    BEGIN
        SELECT @FKeyRemoveQuery='ALTER TABLE dbo.TableName DROP CONSTRAINT [' + LTRIM(RTRIM([name])) + ']'   
        FROM sys.foreign_keys
        WHERE parent_object_id = OBJECT_ID(N'dbo.TableName')
    
        EXECUTE Sp_executesql @FKeyRemoveQuery 
    
    END
    
    0 讨论(0)
  • 2020-12-04 06:06

    You can use those queries to find all FKs for your table.

    Declare @SchemaName VarChar(200) = 'Schema Name'
    Declare @TableName VarChar(200) = 'Table name'
    
    -- Find FK in This table.
    SELECT 
        'IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N''' + 
          '[' + OBJECT_SCHEMA_NAME(FK.parent_object_id) + '].[' + FK.name + ']' 
          + ''') AND parent_object_id = OBJECT_ID(N''' + 
          '[' + OBJECT_SCHEMA_NAME(FK.parent_object_id) + '].[' 
          + OBJECT_NAME(FK.parent_object_id) + ']' + ''')) ' +
    
        'ALTER TABLE ' +  OBJECT_SCHEMA_NAME(FK.parent_object_id) +
        '.[' + OBJECT_NAME(FK.parent_object_id) + 
        '] DROP CONSTRAINT ' + FK.name
        , S.name , O.name, OBJECT_NAME(FK.parent_object_id)
    FROM sys.foreign_keys AS FK
    INNER JOIN Sys.objects As O 
      ON (O.object_id = FK.parent_object_id )
    INNER JOIN SYS.schemas AS S 
      ON (O.schema_id = S.schema_id)  
    WHERE 
          O.name = @TableName
          And S.name = @SchemaName
    
    
    -- Find the FKs in the tables in which this table is used
      SELECT 
        ' IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N''' + 
          '[' + OBJECT_SCHEMA_NAME(FK.parent_object_id) + '].[' + FK.name + ']' 
          + ''') AND parent_object_id = OBJECT_ID(N''' + 
          '[' + OBJECT_SCHEMA_NAME(FK.parent_object_id) + '].[' 
          + OBJECT_NAME(FK.parent_object_id) + ']' + ''')) ' +
    
        ' ALTER TABLE ' +  OBJECT_SCHEMA_NAME(FK.parent_object_id) +
        '.[' + OBJECT_NAME(FK.parent_object_id) + 
        '] DROP CONSTRAINT ' + FK.name
        , S.name , O.name, OBJECT_NAME(FK.parent_object_id)
    FROM sys.foreign_keys AS FK
    INNER JOIN Sys.objects As O 
      ON (O.object_id = FK.referenced_object_id )
    INNER JOIN SYS.schemas AS S 
      ON (O.schema_id = S.schema_id)  
    WHERE 
          O.name = @TableName
          And S.name = @SchemaName 
    
    0 讨论(0)
  • 2020-12-04 06:07
    IF (OBJECT_ID('DF_Constraint') IS NOT NULL)
    BEGIN
        ALTER TABLE [dbo].[tableName]
        DROP CONSTRAINT DF_Constraint
    END
    
    0 讨论(0)
提交回复
热议问题