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.