복붙노트

[SQL] 이 SQL 서버에 존재하는 경우에만 어떻게 외래 키 제약 조건을 삭제합니까?

SQL

이 SQL 서버에 존재하는 경우에만 어떻게 외래 키 제약 조건을 삭제합니까?

그것은 다음과 같은 코드를 사용하여 존재하지만 제약 조건과 동일한 작업을 수행하는 방법을 모른다면 나는 테이블을 삭제할 수 있습니다 :

IF EXISTS(SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'TableName') AND type = (N'U')) DROP TABLE TableName
go 

나는이 코드를 사용하여 제약 조건을 추가 :

ALTER TABLE [dbo].[TableName] 
  WITH CHECK ADD CONSTRAINT [FK_TableName_TableName2] FOREIGN KEY([FK_Name])
    REFERENCES [dbo].[TableName2] ([ID])
go

해결법

  1. ==============================

    1.더 간단한 해결책은 에릭 이삭의 대답에 제공됩니다. 그러나, 모든 테이블에 제약 조건을 찾을 수 있습니다. 특정 테이블에 외래 키 제약 조건을 대상으로 할 경우, 이것을 사용 :

    더 간단한 해결책은 에릭 이삭의 대답에 제공됩니다. 그러나, 모든 테이블에 제약 조건을 찾을 수 있습니다. 특정 테이블에 외래 키 제약 조건을 대상으로 할 경우, 이것을 사용 :

    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]
    
  2. ==============================

    2.이것은 현재 제안 된 솔루션보다 훨씬 간단하다 :

    이것은 현재 제안 된 솔루션보다 훨씬 간단하다 :

    IF (OBJECT_ID('dbo.FK_ConstraintName', 'F') IS NOT NULL)
    BEGIN
        ALTER TABLE dbo.TableName DROP CONSTRAINT FK_ConstraintName
    END
    

    당신은 제약의 또 다른 유형을 삭제해야하는 경우, 이들은 두 번째 매개 변수 위치에 OBJECT_ID () 함수에 전달하는 해당 코드입니다 :

    C = CHECK constraint
    D = DEFAULT (constraint or stand-alone)
    F = FOREIGN KEY constraint
    PK = PRIMARY KEY constraint
    UQ = UNIQUE constraint
    

    또한 두 번째 매개 변수없이 OBJECT_ID를 사용할 수 있습니다.

    여기 유형의 전체 목록 :

    개체 유형 :

    SQL 서버 2014 SQL 서버 2012 :에 적용됩니다.

  3. ==============================

    3.SQL 서버 2016는 DROP IF가 존재 사용할 수 있습니다 :

    SQL 서버 2016는 DROP IF가 존재 사용할 수 있습니다 :

    CREATE TABLE t(id int primary key, 
                   parentid int
                        constraint tpartnt foreign key references t(id))
    GO
    ALTER TABLE t
    DROP CONSTRAINT IF EXISTS tpartnt
    GO
    DROP TABLE IF EXISTS t
    

    http://blogs.msdn.com/b/sqlserverstorageengine/archive/2015/11/03/drop-if-exists-new-thing-in-sql-server-2016.aspx 참조

  4. ==============================

    4.

    IF (OBJECT_ID('DF_Constraint') IS NOT NULL)
    BEGIN
        ALTER TABLE [dbo].[tableName]
        DROP CONSTRAINT DF_Constraint
    END
    
  5. ==============================

    5.당신이 실제 제약 조건의 이름을 알고있는 경우에 제임스의 대답은 잘 작동합니다. 까다로운 것은 기존과 다른 실제 시나리오에서 당신은 제약라는 것을 모를 수 있다는 것이다.

    당신이 실제 제약 조건의 이름을 알고있는 경우에 제임스의 대답은 잘 작동합니다. 까다로운 것은 기존과 다른 실제 시나리오에서 당신은 제약라는 것을 모를 수 있다는 것이다.

    이 경우 당신은 당신이 사용할 수 있습니다 피하기 위해 중복 된 제약 조건을 생성 위험 :

    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
    
  6. ==============================

    6.

    ALTER TABLE [dbo].[TableName]
        DROP CONSTRAINT FK_TableName_TableName2
    
  7. ==============================

    7.

    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
    
  8. ==============================

    8.나는 당신이 의지가 도움이 생각 ...

    나는 당신이 의지가 도움이 생각 ...

        DECLARE @ConstraintName nvarchar(200)
    SELECT 
        @ConstraintName = KCU.CONSTRAINT_NAME
    FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC 
    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU
        ON KCU.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG  
        AND KCU.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA 
        AND KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
    WHERE
        KCU.TABLE_NAME = 'TABLE_NAME' AND
        KCU.COLUMN_NAME = 'TABLE_COLUMN_NAME'
    IF @ConstraintName IS NOT NULL EXEC('alter table TABLE_NAME drop  CONSTRAINT ' + @ConstraintName)
    

    그것은 특정 테이블과 열을 기준으로 외래 키 제약 조건을 삭제합니다.

  9. ==============================

    9.당신은 당신의 테이블의 모든 FKS을 찾기 위해 그 쿼리를 사용할 수 있습니다.

    당신은 당신의 테이블의 모든 FKS을 찾기 위해 그 쿼리를 사용할 수 있습니다.

    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 
    
  10. ==============================

    10.이 질문에 허용 대답은 나를 위해 작동하지 않습니다. 나는 약간 다른 방법으로 같은 일을 달성 :

    이 질문에 허용 대답은 나를 위해 작동하지 않습니다. 나는 약간 다른 방법으로 같은 일을 달성 :

    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
    
  11. from https://stackoverflow.com/questions/482885/how-do-i-drop-a-foreign-key-constraint-only-if-it-exists-in-sql-server by cc-by-sa and MIT license