175

このようにデータベース内のすべてのテーブルを削除したい場合、外部キー制約は処理されますか?そうでない場合は、最初にどのように対処しますか?

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]
4

16 に答える 16

367

いいえ、それを参照している外部キーが実際に存在する場合、これによってテーブルが削除されることはありません。

テーブルを参照するすべての外部キー関係を取得するには、次のSQLを使用できます(SQL Server 2005以降を使用している場合)。

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

そして、もしあれば、ここでこのステートメントを使用して、それらのFK関係を実際に削除するSQLステートメントを作成できます。

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')
于 2009-11-21T17:24:51.273 に答える
52

SQL Server Management Studio 2008 (R2) 以降では、

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

  • ドロップするテーブルを選択します。

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

  • 詳細設定ボタンをクリックします。

  • Script DROP と CREATE を Script DROP に設定します。

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

  • [OK] をクリックします。

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

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

于 2013-09-11T14:23:21.160 に答える
26

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

于 2009-11-21T17:24:20.883 に答える
20

手順を使用して、すべてのテーブルを正しく削除する別の方法を次に示しsp_MSdropconstraintsます。私が考えることができる最短のコード:

exec sp_MSforeachtable "declare @name nvarchar(max); set @name = parsename('?', 1); exec sp_MSdropconstraints @name";
exec sp_MSforeachtable "drop table ?";
于 2014-10-13T20:04:55.810 に答える
2

SQL Serverの場合は、テーブルを削除する前に制約を削除する必要があります。

于 2009-11-21T17:23:18.093 に答える
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')

テーブル名を差し込んで、その結果を実行するだけです。

于 2015-06-09T13:03:38.863 に答える
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
于 2013-12-27T10:06:50.110 に答える
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)
于 2013-12-12T21:57:52.780 に答える
-1

my sql サーバー ( MS SQL ではない) を使用していて、テーブルが失われても構わない場合は、簡単なクエリを使用して一度に複数のテーブルを削除できます。

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

このように、クエリでテーブルを使用する順序は問題ではありません。

多くのテーブルを持つデータベースがある場合、これは良い解決策ではないという事実について誰かが何か言うとしたら、同意します!

于 2016-07-19T16:07:00.703 に答える
-9

データベース内のすべてのテーブルを削除したい場合

次に、データベース全体を削除する方がはるかに簡単です。

DROP DATABASE WorkerPensions
于 2009-11-21T18:03:20.570 に答える