テーブル A とテーブル B があるとします。テーブル B はテーブル A を参照しています。テーブル A とテーブル B の一連の行をディープ コピーしたいと考えています。新しいテーブル B のすべての行が新しいテーブル A の行を参照するようにしたいと考えています。
行を他のテーブルにコピーしていないことに注意してください。テーブル A の行はテーブル A にコピーされ、テーブル B の行はテーブル B にコピーされます。
外部キー参照がコピーの一部として再調整されるようにするにはどうすればよいですか?
明確にするために、これを行う一般的な方法を見つけようとしています。私が示している例には 2 つのテーブルが含まれていますが、実際の依存関係グラフはもっと複雑になる場合があります。作業を行うために SQL を動的に生成する一般的な方法でも問題ありません。
アップデート:
なぜこれが必要なのかと聞かれるので、背景を説明します。多すぎるかもしれませんが、次のようになります。
クライアント サーバー モデルに移行した古いデスクトップ アプリケーションを使用しています。ただし、アプリケーションは依然として基本的な社内バイナリ ファイル形式を使用して、テーブルのデータを格納しています。データ ファイルはヘッダーの後に一連の行が続くものであり、各行はバイナリ シリアル化されたフィールド値であり、その順序はスキーマ テキスト ファイルによって決定されます。それについての唯一の良いことは、それが非常に速いということです。それは他のすべての点でひどいです。アプリケーションを SQL Server に移行し、パフォーマンスをあまり低下させないようにしています。
これはスケジューリング アプリケーションの一種です。データは誰にとっても重要ではなく、監査追跡なども必要ありません。これは膨大な量のデータではなく、データベースが大きくなりすぎた場合に、必ずしも非常に古いデータを保持する必要はありません。
彼らが慣れ親しんでいる機能の 1 つは、スケジュール全体を複製して、いじくり回すことができる「what-if」シナリオを作成する機能です。どのユーザーも、これを何度でも、何度でも実行できます。古いデータベースでは、各スケジュールのデータ ファイルは、名前で識別される独自のデータ フォルダーに保存されます。そのため、スケジュールのコピーは、データ フォルダーをコピーして名前を変更するのと同じくらい簡単でした。
SQL Server で同じことを効果的に実行できなければ、移行は機能しません。冗長性を避けるために、実際に変更されるデータのみをコピーできると考えているかもしれません。しかし、それは正直なところ、実行するには複雑すぎるように思えます。
ミックスに別のレンチを投入するために、スケジュール データ フォルダーの階層が存在する可能性があります。したがって、データ フォルダにはデータ フォルダが含まれる場合があり、データ フォルダにはデータ フォルダが含まれる場合があります。また、コピーはどのレベルでも発生する可能性があります。
SQL Server では、これを模倣するためにネストされたセット階層を実装しています。次のような DATA_SET テーブルがあります。
CREATE TABLE dbo.DATA_SET
(
DATA_SET_ID UNIQUEIDENTIFIER PRIMARY KEY,
NAME NVARCHAR(128) NOT NULL,
LFT INT NOT NULL,
RGT INT NOT NULL
)
つまり、データセットのツリー構造があります。各データ セットはスケジュールを表し、子データ セットを含む場合があります。すべてのテーブルのすべての行には、属しているデータ セットを示す DATA_SET_ID FK 参照があります。データ セットをコピーするときは常に、そのデータ セットのテーブル内のすべての行と他のすべてのデータ セットを同じテーブルにコピーしますが、新しいデータ セットを参照します。
だから、ここに簡単で具体的な例があります:
CREATE TABLE FOO
(
FOO_ID BIGINT PRIMARY KEY,
DATA_SET_ID BIGINT FOREIGN KEY REFERENCES DATA_SET(DATA_SET_ID) NOT NULL
)
CREATE TABLE BAR
(
BAR_ID BIGINT PRIMARY KEY,
DATA_SET_ID BIGINT FOREIGN KEY REFERENCES DATA_SET(DATA_SET_ID) NOT NULL,
FOO_ID UNIQUEIDENTIFIER PRIMARY KEY
)
INSERT INTO FOO
SELECT 1, 1 UNION ALL
SELECT 2, 1 UNION ALL
SELECT 3, 1 UNION ALL
INSERT INTO BAR
SELECT 1, 1, 1
SELECT 2, 1, 2
SELECT 3, 1, 3
では、データ セット 1 を ID 2 の新しいデータ セットにコピーするとします。コピー後、テーブルは次のようになります。
FOO
FOO_ID, DATA_SET_ID
1 1
2 1
3 1
4 2
5 2
6 2
BAR
BAR_ID, DATA_SET_ID, FOO_ID
1 1 1
2 1 2
3 1 3
4 2 4
5 2 5
6 2 6
ご覧のとおり、新しい BAR 行は新しい FOO 行を参照しています。私が求めているのは、DATA_SET_ID の再配線ではありません。一般的に外部キーの再配線について質問しています。
というわけで、確かに情報が多すぎましたが、これで終わりです。
このようにデータを一括コピーするという考え方には、パフォーマンスに関する懸念がたくさんあると思います。テーブルは巨大になることはありません。どのテーブルにも 1000 を超えるレコードがあるとは考えていません。ほとんどのテーブルはそれよりはるかに小さくなります。古いデータ セットは、何の影響もなく完全に削除できます。
ありがとう、テダーツ