このようにデータベース内のすべてのテーブルを削除したい場合、外部キー制約は処理されますか?そうでない場合は、最初にどのように対処しますか?
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]
このようにデータベース内のすべてのテーブルを削除したい場合、外部キー制約は処理されますか?そうでない場合は、最初にどのように対処しますか?
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]
いいえ、それを参照している外部キーが実際に存在する場合、これによってテーブルが削除されることはありません。
テーブルを参照するすべての外部キー関係を取得するには、次の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')
SQL Server Management Studio 2008 (R2) 以降では、
DB -> タスク -> スクリプトの生成
ドロップするテーブルを選択します。
[新しいクエリ ウィンドウに保存] を選択します。
詳細設定ボタンをクリックします。
Script DROP と CREATE を Script DROP に設定します。
スクリプトの外部キーを True に設定します。
[OK] をクリックします。
[次へ] -> [次へ] -> [完了] をクリックします。
スクリプトを表示し、実行します。
最初に「子」テーブルを削除すると、外部キーも削除されます。最初に「親」テーブルを削除しようとすると、「FOREIGN KEY制約によって参照されているため、オブジェクト'a'を削除できませんでした」というメッセージが表示されます。エラー。
手順を使用して、すべてのテーブルを正しく削除する別の方法を次に示しsp_MSdropconstraints
ます。私が考えることができる最短のコード:
exec sp_MSforeachtable "declare @name nvarchar(max); set @name = parsename('?', 1); exec sp_MSdropconstraints @name";
exec sp_MSforeachtable "drop table ?";
SQL Serverの場合は、テーブルを削除する前に制約を削除する必要があります。
@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')
テーブル名を差し込んで、その結果を実行するだけです。
ソリューションを実装するための完全なスクリプトを次に示します。
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
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)
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;
このように、クエリでテーブルを使用する順序は問題ではありません。
多くのテーブルを持つデータベースがある場合、これは良い解決策ではないという事実について誰かが何か言うとしたら、同意します!
データベース内のすべてのテーブルを削除したい場合
次に、データベース全体を削除する方がはるかに簡単です。
DROP DATABASE WorkerPensions