2

現在、ツリーのような構造の DB で作業しています。基本的にトップレベルのテーブルが 1 つあり、そのテーブルに外部キーを持つテーブルが約 10 あります。これらの各テーブルには、外部キー制約を持つ別の 10 個のテーブルがあります。私の目標は、メインテーブルからいくつかのレコードを削除し、子、孫なども削除することですが、もちろん外部キーによりこれは骨の折れる作業になります。

私は少し検索して、カスケード削除の使用に関するこの質問を確認しました。少数のテーブルのみを扱っている場合、これでうまくいくと思います。しかし、私の現在の設定では、100 を超えるテーブルを 1 つずつ変更するのはまだ快適ではありません。

したがって、多くのテーブルが関係している場合に、外部キーを持つ値を簡単に削除する方法があるかどうかを尋ねています。

比較的小さな DB をある程度制御できるので、クエリの効率と、他のユーザーによって値が削除されるリスクは、実際には問題になりません。したがって、すべてのテーブルにカスケード削除を適用するのは簡単かもしれませんが、私は完全に異なるソリューションにもオープンです (Microsoft Server Studio 2008 で T-SQL を使用)。

4

5 に答える 5

2

これを見ましたか?この男は、データベースの外部キー関係に基づいて削除ステートメントを自動生成しています。

SQL 2008 で外部キー関係から削除ステートメントを生成しますか?

私は個人的にそれの大ファンではありませんが、試してみる価値があります。

于 2013-01-23T16:27:32.593 に答える
1

カスケード削除は、「メイン」テーブルに適したソリューションです。

すべてのテーブルを手動で変更することを避けるために、スクリプトを使用できます。ここにあるように、小さな変更 (最後の行、<yourTable>テーブル名で変更) があります。

select
  DropStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema + 
      '].[' + ForeignKeys.ForeignTableName + 
      '] DROP CONSTRAINT [' + ForeignKeys.ForeignKeyName + ']; '
,  CreateStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema + 
      '].[' + ForeignKeys.ForeignTableName + 
      '] WITH CHECK ADD CONSTRAINT [' +  ForeignKeys.ForeignKeyName + 
      '] FOREIGN KEY([' + ForeignKeys.ForeignTableColumn + 
      ']) REFERENCES [' + schema_name(sys.objects.schema_id) + '].[' +
  sys.objects.[name] + ']([' +
  sys.columns.[name] + ']) ON DELETE CASCADE; '
 from sys.objects
  inner join sys.columns
    on (sys.columns.[object_id] = sys.objects.[object_id])
  inner join (
    select sys.foreign_keys.[name] as ForeignKeyName
     ,schema_name(sys.objects.schema_id) as ForeignTableSchema
     ,sys.objects.[name] as ForeignTableName
     ,sys.columns.[name]  as ForeignTableColumn
     ,sys.foreign_keys.referenced_object_id as referenced_object_id
     ,sys.foreign_key_columns.referenced_column_id as referenced_column_id
     from sys.foreign_keys
      inner join sys.foreign_key_columns
        on (sys.foreign_key_columns.constraint_object_id
          = sys.foreign_keys.[object_id])
      inner join sys.objects
        on (sys.objects.[object_id]
          = sys.foreign_keys.parent_object_id)
        inner join sys.columns
          on (sys.columns.[object_id]
            = sys.objects.[object_id])
           and (sys.columns.column_id
            = sys.foreign_key_columns.parent_column_id)
    ) ForeignKeys
    on (ForeignKeys.referenced_object_id = sys.objects.[object_id])
     and (ForeignKeys.referenced_column_id = sys.columns.column_id)
 where (sys.objects.[type] = 'U')
  and (sys.objects.[name]  = '<yourTable>')

最初の列の結果を Management Studio クエリ ウィンドウにコピーして実行し、2 番目の列で同じことを行うと、完了です。

于 2013-01-23T16:27:19.400 に答える
1

このようなことを別の方法で行う最善の方法は、「ステータス」という名前の列を使用してロジックの削除を使用することだと思います。これにより、そのフィールドがまだプログラムロジックの下で考慮されるかどうかを制御します。ステータス列は、最上位テーブルでのみ作成する必要があります。SQL ステートメントでは、「where status = 1」などを挿入します。

質問に対するまったく異なるアプローチであるため、それが役立つことを願っています。

于 2013-01-23T16:14:55.620 に答える
0

データの整合性を犠牲にしたくない場合は、T_SQL CASCADE DELETE オプションを使用してください。「ALTER TABLE PARENT1 ADD FOREIGN KEY」を作成し、コピーして安全なソリューションに貼り付けることができます。

これは、Mgmt などのサードパーティ プログラムを介して削除ステートメントが発行された場合に実行されないプログラム ソリューションの開発とテストよりもはるかに短い時間で済みます。スタジオ。

于 2013-01-23T16:29:06.253 に答える
-1

あなたが参照した質問で述べたように、を使用して自動的に削除を処理できますON DELETE CASCADE

于 2013-01-23T16:28:44.247 に答える