SQL DROP TABLE 외래 키 제약 조건


154

이와 같이 데이터베이스의 모든 테이블을 삭제하려면 외래 키 제약 조건을 처리합니까? 그렇지 않다면 어떻게해야합니까?

GO
IF OBJECT_ID('dbo.[Course]','U') IS NOT NULL
    DROP TABLE dbo.[Course]
GO
IF OBJECT_ID('dbo.[Student]','U') IS NOT NULL
    DROP TABLE dbo.[Student]


2
이 답변을 확인, 그것은 나에게 도움) stackoverflow.com/a/5488670/2205144을
— xatz

답변:


335

아니요, 실제로 참조하는 외래 키가 있으면 테이블이 삭제되지 않습니다.

테이블을 참조하는 모든 외래 키 관계를 얻으려면이 SQL을 사용할 수 있습니다 (SQL Server 2005 이상인 경우).

SELECT * 
FROM sys.foreign_keys
WHERE referenced_object_id = object_id('Student')

이 문장이 있으면 SQL 문을 만들어 실제로 FK 관계를 삭제할 수 있습니다.

SELECT 
    'ALTER TABLE [' +  OBJECT_SCHEMA_NAME(parent_object_id) +
    '].[' + OBJECT_NAME(parent_object_id) + 
    '] DROP CONSTRAINT [' + name + ']'
FROM sys.foreign_keys
WHERE referenced_object_id = object_id('Student')

참고 : 생성 된 테이블에는 다른 조회에서 실행될 개별 제한 조건을 삭제하는 명령문이 있습니다. FK가있는 나머지 테이블을 그대로 유지하면서 테스트 목적으로 쓸모없는 테이블을 제거해야했기 때문에 놀라운 일이었습니다.
— Mauricio Quintana

1
언급 된 objects_id 대신 parent_object_id를 사용해야했습니다
— Tom Robinson

2
모든 참조 테이블을 얻기위한 SELECT 문의 대안은 다음과 같습니다. EXEC sp_fkeys 'Student';
— Buggieboy

이 쿼리의 작은 조정 SELECT 'ALTER TABLE'+ OBJECT_SCHEMA_NAME (parent_object_id) + '. ['+ OBJECT_NAME (parent_object_id) + '] DROP CONSTRAINT [name]'FROM sys.foreign_keys WHERE reference_object_id = object_id ( 'Student') 바꾸기 [name] CONSTRAINT 이름으로
— Stas Svishov 2018 년

1
마지막 선택을 변수로 지정하고 실행하는 방법은 무엇입니까?
— Hrvoje T

44

SQL Server Management Studio 2008 (R2) 이상에서는 마우스 오른쪽 단추로

DB-> 작업-> 스크립트 생성

  • 삭제하려는 테이블을 선택하십시오.

  • "새 쿼리 창에 저장"을 선택하십시오.

  • 고급 버튼을 클릭하십시오.

  • 스크립트 DROP 및 CREATE를 스크립트 DROP으로 설정하십시오.

  • 스크립트 외래 키를 True로 설정하십시오.

  • 확인을 클릭하십시오.

  • 다음-> 다음-> 완료를 클릭하십시오.

  • 스크립트를 본 다음 실행하십시오.


12
FOREIGN KEY 제약 조건에 의해 참조되므로 동일한 ''my_table '개체를 삭제할 수 없습니다.
— FrenkyB

6
이 답변에 28 + 등급이있는 방법은 저쪽에 있습니다 ... 아직도 배우자가되지 않습니다
— AltF4_

1
스크립트를 생성하는 동안 –이 스크립트는 문제를 해결하지 못하는데, 이는 외래 키 제약 조건에 의해 참조되는 테이블을 삭제하는 것입니다.
— Alexey Shevelyov

나를 위해 매력처럼 일했습니다.
— 요한

21

"자식"테이블을 먼저 삭제하면 외래 키도 삭제됩니다. "부모"테이블을 먼저 삭제하려고하면 "FOREIGN KEY 제약 조건에 의해 참조되므로 개체 'a'를 삭제할 수 없습니다."가 표시됩니다. 오류.


2
사실이지만 해결책은 없습니다. 자식은 테이블에 외래 키를 가질 수 있으며 처음에는 떨어 뜨리고 싶지 않을 수도 있습니다.
— MaR

4
"내 데이터베이스의 모든 테이블을 삭제하려는 경우 ..."라는 목표가있을 경우 해결책이됩니다.
— Philip Kelley 2011

4
질문자가 "내 데이터베이스의 모든 테이블을 삭제"하고 싶다는 점을 고려하면 이것은 허용 된 것보다 훨씬 더 나은 대답입니다.
— lukkea

17

다음은 sp_MSdropconstraints프로 시저를 사용하여 모든 테이블을 올바르게 삭제하는 다른 방법 입니다. 내가 생각할 수있는 가장 짧은 코드 :

exec sp_MSforeachtable "declare @name nvarchar(max); set @name = parsename('?', 1); exec sp_MSdropconstraints @name";
exec sp_MSforeachtable "drop table ?";

멋진 남자 ............
— edCoder


2

@mark_s가 게시 한 것의 약간 더 일반적인 버전으로 인해 도움이되었습니다.

SELECT 
'ALTER TABLE ' +  OBJECT_SCHEMA_NAME(k.parent_object_id) +
'.[' + OBJECT_NAME(k.parent_object_id) + 
'] DROP CONSTRAINT ' + k.name
FROM sys.foreign_keys k
WHERE referenced_object_id = object_id('your table')

테이블 이름을 연결하고 결과를 실행하십시오.


1
안녕하세요, 위의 외래 키 제약 조건을 삭제하려고 시도했지만 나중에 테이블을 삭제하려고하면 "외래 키 제약 조건에서 여전히 참조하고 있기 때문에 객체를 삭제할 수 없습니다 ... 어떤 아이디어라도 미리 감사드립니다
— daniness

1

FOR XML PATH('')여러 입력 행을 단일 출력 행으로 병합 할 수 있는 연결 트릭을 사용하여 테이블 자체가 뒤 따르는 모든 제약 조건을 삭제하는 또 다른 방법 이 있습니다. SQL 2005 이상에서 작동해야합니다.

EXECUTE 명령은 안전을 위해 주석 처리되었습니다.

DECLARE @SQL NVARCHAR(max)
;WITH fkeys AS (
    SELECT quotename(s.name) + '.' + quotename(o.name) tablename, quotename(fk.name) constraintname 
    FROM sys.foreign_keys fk
    JOIN sys.objects o ON fk.parent_object_id = o.object_id
    JOIN sys.schemas s ON o.schema_id = s.schema_id
)
SELECT @SQL = STUFF((SELECT '; ALTER TABLE ' + tablename + ' DROP CONSTRAINT ' + constraintname
FROM fkeys
FOR XML PATH('')),1,2,'')

-- EXECUTE(@sql)

SELECT @SQL = STUFF((SELECT '; DROP TABLE ' + quotename(TABLE_SCHEMA) + '.' + quotename(TABLE_NAME) 
FROM INFORMATION_SCHEMA.TABLES 
FOR XML PATH('')),1,2,'')

-- EXECUTE(@sql)

모든 FK가 삭제되는 것은 아니기 때문에 잘 작동하지 않습니다 (테이블이 부모로 사용되는 테이블 만, "참조 된"테이블이 사용 된 위치를 삭제해야하는 테이블 만).
— Roman Pokrovskij

로마의 원래 게시물은 외래 키 제약 조건을 삭제하는 것입니다. 내 대답은 그 이상을 다루는 것을 목표로하지 않습니다.
— 워렌 루막

1

솔루션을 구현하기위한 완전한 스크립트는 다음과 같습니다.

create Procedure [dev].DeleteTablesFromSchema
(
    @schemaName varchar(500)
)
As 
begin
    declare @constraintSchemaName nvarchar(128), @constraintTableName nvarchar(128),  @constraintName nvarchar(128)
    declare @sql nvarchar(max)
    -- delete FK first
    declare cur1 cursor for
    select distinct 
    CASE WHEN t2.[object_id] is NOT NULL  THEN  s2.name ELSE s.name END as SchemaName,
    CASE WHEN t2.[object_id] is NOT NULL  THEN  t2.name ELSE t.name END as TableName,
    CASE WHEN t2.[object_id] is NOT NULL  THEN  OBJECT_NAME(d2.constraint_object_id) ELSE OBJECT_NAME(d.constraint_object_id) END as ConstraintName
    from sys.objects t 
        inner join sys.schemas s 
            on t.[schema_id] = s.[schema_id]
        left join sys.foreign_key_columns d 
            on  d.parent_object_id = t.[object_id]
        left join sys.foreign_key_columns d2 
            on  d2.referenced_object_id = t.[object_id]
        inner join sys.objects t2 
            on  d2.parent_object_id = t2.[object_id]
        inner join sys.schemas s2 
            on  t2.[schema_id] = s2.[schema_id]
    WHERE t.[type]='U' 
        AND t2.[type]='U'
        AND t.is_ms_shipped = 0 
        AND t2.is_ms_shipped = 0 
        AND s.Name=@schemaName
    open cur1
    fetch next from cur1 into @constraintSchemaName, @constraintTableName, @constraintName
    while @@fetch_status = 0
    BEGIN
        set @sql ='ALTER TABLE ' + @constraintSchemaName + '.' + @constraintTableName+' DROP CONSTRAINT '+@constraintName+';'
        exec(@sql)
        fetch next from cur1 into @constraintSchemaName, @constraintTableName, @constraintName
    END
    close cur1
    deallocate cur1

    DECLARE @tableName nvarchar(128)
    declare cur2 cursor for
    select s.Name, p.Name
    from sys.objects p
        INNER JOIN sys.schemas s ON p.[schema_id] = s.[schema_id]
    WHERE p.[type]='U' and is_ms_shipped = 0 
    AND s.Name=@schemaName
    ORDER BY s.Name, p.Name
    open cur2

    fetch next from cur2 into @schemaName,@tableName
    while @@fetch_status = 0
    begin
        set @sql ='DROP TABLE ' + @schemaName + '.' + @tableName
        exec(@sql)
        fetch next from cur2 into @schemaName,@tableName
    end

    close cur2
    deallocate cur2

end
go

1
Removing Referenced FOREIGN KEY Constraints
Assuming there is a parent and child table Relationship in SQL Server:

--First find the name of the Foreign Key Constraint:
  SELECT * 
  FROM sys.foreign_keys
  WHERE referenced_object_id = object_id('States')

--Then Find foreign keys referencing to dbo.Parent(States) table:
   SELECT name AS 'Foreign Key Constraint Name', 
           OBJECT_SCHEMA_NAME(parent_object_id) + '.' + OBJECT_NAME(parent_object_id) AS 'Child Table'
   FROM sys.foreign_keys 
   WHERE OBJECT_SCHEMA_NAME(referenced_object_id) = 'dbo' AND 
              OBJECT_NAME(referenced_object_id) = 'dbo.State'

 -- Drop the foreign key constraint by its name 
   ALTER TABLE dbo.cities DROP CONSTRAINT FK__cities__state__6442E2C9;

 -- You can also use the following T-SQL script to automatically find 
 --and drop all foreign key constraints referencing to the specified parent 
 -- table:

 BEGIN

DECLARE @stmt VARCHAR(300);

-- Cursor to generate ALTER TABLE DROP CONSTRAINT statements  
 DECLARE cur CURSOR FOR
 SELECT 'ALTER TABLE ' + OBJECT_SCHEMA_NAME(parent_object_id) + '.' + 
 OBJECT_NAME(parent_object_id) +
                ' DROP CONSTRAINT ' + name
 FROM sys.foreign_keys 
 WHERE OBJECT_SCHEMA_NAME(referenced_object_id) = 'dbo' AND 
            OBJECT_NAME(referenced_object_id) = 'states';

 OPEN cur;
 FETCH cur INTO @stmt;

 -- Drop each found foreign key constraint 
  WHILE @@FETCH_STATUS = 0
  BEGIN
    EXEC (@stmt);
    FETCH cur INTO @stmt;
  END

  CLOSE cur;
  DEALLOCATE cur;

  END
  GO

--Now you can drop the parent table:

 DROP TABLE states;
--# Command(s) completed successfully.

0

SQL Server Manager를 사용하면 UI에서 외래 키 제약 조건을 삭제할 수 있습니다. 테이블을 삭제하려고 Diary하지만 사용자 테이블에 테이블을 DiaryId가리키는 외래 키가있는 경우 Diary테이블을 확장 (플러스 기호 사용) User한 다음 Foreign Keys섹션 을 확장 할 수 있습니다. 일기 테이블을 가리키는 외래 키를 마우스 오른쪽 버튼으로 클릭하고을 선택 Delete합니다. 그런 다음 Columns섹션 을 확장하고 마우스 오른쪽 버튼을 클릭하고 열도 삭제할 수 DiaryId있습니다. 그런 다음 다음을 실행할 수 있습니다.

drop table Diary

귀하의 실제 질문은 모든 테이블을 삭제하는 것에 관한 것이므로이 경우에는 유용하지 않을 수 있습니다. 그러나 일부 테이블을 삭제하려는 경우 유용합니다 (제목에 모든 테이블 삭제를 명시 적으로 언급하지는 않음).


0

mysql 서버에 있고 테이블을 잃어 버리지 않는다면 간단한 쿼리를 사용하여 여러 테이블을 한 번에 삭제할 수 있습니다.

SET foreign_key_checks = 0;
DROP TABLE IF EXISTS table_a,table_b,table_c,table_etc;
SET foreign_key_checks = 1;

이런 식으로 쿼리에서 테이블을 사용하는 순서는 중요하지 않습니다.

테이블이 많은 데이터베이스가있는 경우 이것이 좋은 해결책이 아니라는 사실에 대해 누군가 이야기 할 것이라면 동의합니다!


나는 얻는다Incorrect syntax near '='. (102) (SQLExecDirectW)
— Matt

@Matt 어느 '='에서 추측하기 어려운 비트는 그 오류가 발생합니다.
— Els den Iep

3
foreign_key_checksMSSQL 서버에서는 작동하지 않습니다. 나는 그것이 MySql 특정 변수라고 생각합니다.
— ooXei1sh

1
@ ooXei1sh MSSQL에는 없습니다. 그렇기 때문에 게시물을 시작할 때 "MySQL 서버에있는 경우"라고 말합니다.
— Els den Iep

0

드롭 다운을 차단하는 외래 키 제약 조건 이름을 얻으려면 아래 코드를 실행하십시오. 예를 들어, 나는 roles테이블을 가져갑니다 .

      SELECT *
      FROM sys.foreign_keys
      WHERE referenced_object_id = object_id('roles');

      SELECT name AS 'Foreign Key Constraint Name',
      OBJECT_SCHEMA_NAME(parent_object_id) + '.' + OBJECT_NAME(parent_object_id)
      AS 'Child Table' FROM sys.foreign_keys
      WHERE OBJECT_SCHEMA_NAME(referenced_object_id) = 'dbo'
      AND OBJECT_NAME(referenced_object_id) = 'dbo.roles'

다음과 같이 FK 이름을 얻습니다. FK__Table1__roleId__1X1H55C1

이제 아래 코드를 실행하여 위에서 얻은 FK 참조를 제거하십시오.

ALTER TABLE dbo.users drop CONSTRAINT FK__Table1__roleId__1X1H55C1;

끝난!


-4

데이터베이스의 모든 테이블을 삭제하려면

그런 다음 전체 데이터베이스를 삭제하는 것이 훨씬 쉽습니다.

DROP DATABASE WorkerPensions

71
질문에 대한 정답이 아니기 때문에 -1을주는 것은 다음 두 가지 중요한 이유 때문입니다. 1) 테이블보다 더 많은 것을 삭제합니다! 저장 프로 시저, 함수, UDT, 보안, .NET 어셈블리 등은 모두 DROP DATABASE와 함께 사라집니다. 2) IT 부서에서 데이터베이스를 프로비저닝하고 모르는 경우 추가 요구 사항이있는 중앙 관리 개발 환경과 같은 데이터베이스를 만들 수 없습니다.
— 워렌 루막

-4

DROP외래 키를 사용하여 다른 테이블에서 참조한 테이블을 원할 경우

DROP TABLE *table_name* CASCADE CONSTRAINTS;
나는 그것이 당신을 위해 작동해야한다고 생각합니다.


1
어떤이없는 cascade constraintsSQL 서버
— JackyJohnson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.