5

いくつかの既存のテーブルへの外部キー参照を持つ新しいテーブルがあります。新しいテーブルを初めて作成するときは、次の方法で外部キーを作成しました。

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

上記の方法では、独自の自動命名規則を使用して外部キー制約の名前が生成されます。

ただし、新しいテーブルを最初から作成して大きな変更を加える必要があるため、新しいテーブルを削除したいと思います。

明らかに、dropステートメントを実行するだけで、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ステートメントを示す結果を示します。

もっと自動化されたものが必要です。各外部キー制約を個別に削除する必要があるのに、テーブルのみを削除できるのはなぜですか?

もっと簡単な方法でテーブルをドロップしたいと思います。それは私が上でする必要があることよりも簡単でなければなりません。

4

3 に答える 3

4

リレーショナルデータベースは、データベースの整合性を強化するように設計されています。あなたのステートメントは、データ品質を保護するために注意深く追加された制約を破壊する可能性があります。本番データベースからの整合性制約の削除を自動化することは、企業にとって災害になる可能性があります。そのため、SQL言語が開発されたとき、他のテーブルによって参照されているテーブルを簡単に削除できるようにすることは、重要なタスクの優先度では高くありませんでした。エンタープライズデータ用のデータベースエンジンを備えたこの製品は、カジュアルユーザーよりもDBA向けに設計されています。

外部キーで参照されている複数のテーブルを削除したい理由は何ですか?他の人のクエリを破棄しないことを確認できますか?

重要ではないシステムで作業していると仮定すると、ドロップスクリプトを作成するためのスクリプトを作成するというアプローチは、私が知っている最善の解決策です。

于 2012-10-03T19:12:29.920 に答える
3

はい、最初にFKをドロップする必要があります。私は以前にこれに遭遇し、タスクを自動化するために必要なスクリプトだけを書きました。以下のDBNameとTABLENAMEを置き換えます。

すべての人への警告:このスクリプトは、特定のテーブル(またはテーブルのグループ)とすべてのFK制約を削除します!注意して使用し、このような主要な操作を実行する前に、常にデータベースのバックアップを取ります。

    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
于 2012-10-03T19:21:54.387 に答える
1

MSSQLを使用している場合は、私が作成したこのスクリプトを使用して、テーブル自体を削除せずにDB全体をデータから削除できます。

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'

「selectinto」クエリのwhere句で、パージしたくないテーブルを追加できます。お役に立てれば

于 2012-10-03T19:34:38.767 に答える