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
references_object_idの代わりにparent_object_idを使用する必要がありました
Tom Robinson

2
すべての参照テーブルを取得するためのSELECTステートメントの代替は、次のとおりです。EXEC sp_fkeys 'Student';
バギーボーイ、

このクエリの小さな調整SELECT 'ALTER TABLE' + OBJECT_SCHEMA_NAME(parent_object_id)+ '。[' + OBJECT_NAME(parent_object_id)+ '] DROP CONSTRAINT [name]' FROM sys.foreign_keys WHERE linked_object_id = object_id( 'Student')replace [name] CONSTRAINT名
Stas Svishov

1
最後の選択を変数として割り当てて実行する方法は?
Hrvoje T

44

SQL Server Management Studio 2008(R2)以降では、右クリックして

DB->タスク->スクリプトの生成

  • 削除するテーブルを選択します。

  • 「新しいクエリウィンドウに保存」を選択します。

  • [詳細]ボタンをクリックします。

  • Script DROPおよびCREATEをScript DROPに設定します。

  • スクリプト外部キーをTrueに設定します。

  • OKをクリックします。

  • [次へ]-> [次へ]-> [完了]をクリックします。

  • スクリプトを表示して、実行します。


12
FOREIGN KEY制約によって参照されているため、同じ 'オブジェクト' my_table 'を削除できませんでした。
FrenkyB 2015年

6
この回答の28点以上の評価は私を超えています...
相性

1
スクリプトは生成されますが、そのスクリプトは問題を解決しません。これは、外部キー制約によって参照されるテーブルを削除することです。
Alexey Shevelyov

私にとっては魅力のように働きました。
ヨハン

21

最初に「子」テーブルをドロップすると、外部キーもドロップされます。最初に「親」テーブルを削除しようとすると、「オブジェクト 'a'を削除できませんでした。このオブジェクトはFOREIGN KEY制約によって参照されているためです。」エラー。


2
本当ですが、解決策はありません。子供は他のテーブルへの外部キーを持つことができ、および/または最初にそれをドロップしたくない場合があります。
MaR 2009年

4
確かに、目標が「データベース内のすべてのテーブルを削除したい場合...」の場合の解決策
フィリップケリー

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

Roman、元の投稿は、外部キー制約の削除に関するものです。私の答えはそれ以上のものをカバーすることを目指していません。
Warren Rumak 2013

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が、Userテーブルにテーブルを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 16

3
foreign_key_checksMSSQLサーバーでは機能しません。MySql固有の変数だと思います。
ooXei1sh 2016年

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
次の2つの重要な理由から、これは質問に対する有効な回答ではないため、-1を与えます。1)テーブルよりもはるかに多く削除されます!ストアドプロシージャ、関数、UDT、セキュリティ、.NETアセンブリなどはすべて、DROP DATABASEでなくなります。2)データベースの作成が許可されていない場合があります。たとえば、データベースがITによってプロビジョニングされ、作成時に気付かない追加の要件がある中央管理型の開発環境。
Warren Rumak 2013

-4

DROP外部キーを使用して他のテーブルによって参照されているテーブルにしたい場合

DROP TABLE *table_name* CASCADE CONSTRAINTS;
うまくいくと思います。


1
cascade constraintsSQLサーバーにはありません
JackyJohnson '15
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.