2012-10-03 5 views
4

기존 테이블에 외래 키 참조가있는 새 테이블이 있습니다.다른 테이블에 외래 키 참조가있는 테이블을 삭제하는 더 간단하고 빠른 방법이 있습니까?

ALTER TABLE [dbo].[NewTable] WITH CHECK ADD FOREIGN KEY([SectionDatabaseID]) 
REFERENCES [dbo].[Section] ([SectionDatabaseID]) 

ALTER TABLE [dbo].[NewTable] WITH CHECK ADD FOREIGN KEY([TermDatabaseID]) 
REFERENCES [dbo].[Term] ([TermDatabaseID]) 

위의 방법은 자신의 자동화 된 명명 규칙의 사용하여 외래 키 제약 조건의 이름을 생성합니다 : 내가 처음으로 새 테이블을 만들 때, 나는 다음과 같은 방법으로 외부 키를 만들었습니다.

그러나 처음부터 새로 만들어 몇 가지 주요 수정 작업을 수행해야하므로 새 테이블을 삭제하려고합니다.

분명히 방금 SQL 문을 실행하면 SQL Server 데이터베이스는 새 테이블에 다른 테이블에 대한 외래 키 참조가 있음을 알리는 메시지를 표시합니다.

나는 외래 키는 우리가 그들을 삭제할 수 있도록 존재하는 것을 알아 내기 위해 다음과 같은 스크립트를 실행 들었어요 :

use perls; 
SELECT 'ALTER TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME + 
'] DROP CONSTRAINT [' + CONSTRAINT_NAME + ']' 
FROM information_schema.table_constraints 
WHERE CONSTRAINT_TYPE = 'FOREIGN KEY' and TABLE_NAME = 'NewTable' 

은 위 기본적으로 내가 실행해야합니다 ALTER 문을 보여주는 결과를 제공 할 것입니다.

더 자동화 된 것이 필요합니다. 개별 외래 키 제약 조건을 개별적으로 삭제 한 다음 테이블을 삭제할 수 있어야하는 이유는 무엇입니까?

테이블을 더 간단하게 삭제하려고합니다. 위에서해야 할 일보다 쉬워 져야합니다.

+0

다이어그램을 만들고, 모든 테이블을 추가하고, 해당 UI를 통해 FK를 삭제할 수 있습니다. – Beth

+0

다른 테이블을 참조하는 FOREIGN KEY가있는 테이블을 문제없이 제거 할 수 있어야합니다. 문제는 외부 키가 * it *을 참조하는 테이블을 삭제하려고 할 때 발생합니다. 이러한 경우 외래 키를 먼저 찾아서 삭제해야합니다. –

+0

나는'Drop table cascade'를 tsql에서 사용하고 싶다고 생각하니? http://stackoverflow.com/questions/4858488/sql-server-drop-table-cascade-equivalent –

답변

3

예. 먼저 FK를 삭제해야합니다. 전에이 문제에 휩쓸 렸고 작업을 자동화하는 데 필요한 스크립트 만 작성했습니다. 아래의 DBName 및 TABLENAME을 바꾸십시오.

경고 :이 스크립트는 모든 FK 제약 조건뿐만 아니라 특정 테이블 (또는 테이블 그룹)을 삭제합니다! 주의해서 사용해야하며 이와 같은 주요 작업을 수행하기 전에 항상 db 백업을 수행하십시오.

use DBName 
    /* 
    SCRIPT TO DROP TABLES WITH FK'S, INDEXES 
    https://mellodev.snipt.net/drop-tables-with-fk-contraints/ 
    */ 

    set nocount on 

declare @tables table (tablename varchar(255)); 
insert into @tables 
select name from sys.tables where name in 
('TABLENAME') 

-- Iterate tables, drop FK constraints and tables 
declare @tablename varchar(255); 
declare cTable cursor for 
select tablename from @tables 
open cTable 
fetch next from cTable into @tableName 
while @@FETCH_STATUS=0 
begin 
    -- Identify any FK constraints 
    declare @fkCount int; 
    SELECT @fkCount = COUNT(*) 
    FROM sys.foreign_keys 
    WHERE referenced_object_id = object_id(@tablename) 

    -- Drop any FK constraints from the table 
    if (@fkCount>0) begin 
     declare @dropFkSql nvarchar(max);set @dropFkSql=''; 
     declare @fkName nvarchar(max); 
     declare cDropFk cursor for 
      SELECT 'ALTER TABLE [' + OBJECT_NAME(parent_object_id) + '] DROP CONSTRAINT [' + name + ']',name 
      FROM sys.foreign_keys 
      WHERE referenced_object_id = object_id(@tablename) 
     open cDropFk 
     fetch next from cDropFk into @dropfksql,@fkName 
     while @@FETCH_STATUS=0 
     begin  
      exec sp_executesql @dropFkSql; 

      select 'Dropped FK Constraint: ' + @fkName 
      fetch next from cDropFk into @dropfksql,@fkName 
     end 
     close cDropFk 
     deallocate cDropFk   
    end 

    -- Drop the table 
    declare @dropTableSql nvarchar(max); 
    set @dropTableSql='DROP TABLE [' + @tablename + ']'; 
    exec sp_executesql @dropTableSql; 

    select 'Dropped table: ' + @tablename 

    fetch next from cTable into @tableName 
end 
close cTable 
deallocate cTable 
4

관계형 데이터베이스는 데이터베이스 무결성을 강화하도록 설계되었습니다. 귀하의 진술은 잠재적으로 데이터 품질을 보호하기 위해 신중하게 추가 된 제약 조건을 파괴하고 있습니다. 프로덕션 데이터베이스에서 무결성 제약 조건을 자동으로 삭제하면 회사에 재앙이 될 수 있습니다. 그래서 SQL 언어가 개발되었을 때, 다른 테이블에 의해 참조되는 테이블을 쉽게 삭제할 수 있도록하는 것은 중요한 태스크의 우선 순위가 높지 않았습니다. 엔터프라이즈 데이터를위한 데이터베이스 엔진을 통해이 제품은 일반 사용자보다 DBA를 위해 더 많이 설계되었습니다.

외래 키에서 참조되는 여러 테이블을 삭제하려는 이유는 무엇입니까? 다른 사람의 질문을 파기하지 않을 것이라고 확신 할 수 있습니까?

중요하지 않은 시스템에서 작업하고 있다고 가정하면 드롭 스크립트를 작성하기위한 스크립트 작성 방법은 제가 아는 최상의 해결책입니다.

+0

개발 중에 스키마를 수정 한 후에 다시 실행할 수 있도록 테이블 작성 스크립트를 작성하는 것이 매우 일반적입니다. 이 경우 스크립트를 다시 만들기 전에 스크립트에서 만드는 모든 테이블과 제약 조건을 삭제해야합니다. – Crake

1

당신이 그때 당신은 내가 테이블 자체를 삭제하지 않고 데이터에서 전체 DB를 제거하기 위해 쓴이 스크립트를 사용할 수 있습니다 MSSQL을 사용하는 경우.

use [MyDataBase] 
GO 

EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'; 

select tbl.* into dbo.DeleteQueries from (SELECT 'DELETE ' + name + ';' as query 
FROM sys.tables 
WHERE name <> 'DeleteQueries') as tbl 

Declare @query nvarchar(100) 

While (Select Count(*) From dbo.DeleteQueries Where query <> '') > 0 
Begin 
    Select Top 1 @query = query From dbo.DeleteQueries Where query <> '' 

    exec(@query); 

    Update dbo.DeleteQueries Set query = '' Where query = @query 

End 

DROP TABLE dbo.DeleteQueries 

EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL' 

"선택 대상"쿼리의 where 절에서 제거하지 않으려는 테이블을 추가 할 수 있습니다. 희망이 있습니다.