2009-04-12 8 views
10

に更新します。新しいデータベースに移行する古いデータベースがあります。新しいものは少し異なりますが、ほとんど互換性のあるスキーマです。さらに、私は0からすべてのテーブルの番号を付け替えたい。TSQL:INSERT INTO SELECTを使用して

現在、古いレコードを手動で取得して新しいデータベースに挿入し、古いデータベースのv2 IDフィールドを更新して、対応するIDの場所を新しいデータベースに表示するツールを使用しています。

たとえば、私はMV5.Postsから選択し、MV6.Postsに挿入しています。挿入すると、MV6.Postsの新しい行のIDが取得され、古いMV5.Posts.MV6IDフィールドで更新されます。

INSERT INTO SELECT FROMを介してこのUPDATEを実行する方法はありますか?すべてのレコードを手動で処理する必要はありませんか?私はSQL Server 2005の開発版を使用しています。

答えて

9

キーはいくつかのことを行うことです: まず、現在のバックアップなしでは何もしません。 第2に、キーが変更される場合は、少なくとも一時的に新しい構造体にoldとnewの両方を格納する必要があります(古いレコードを取得するためにキーフィールドがユーザーに公開されている場合は、

次に、子テーブルへの関係を完全に理解する必要があります。キーフィールドを変更すると、関連するすべてのテーブルも同様に変更する必要があります。これは古いキーと新しいキーの両方を保存しておくと便利です。それらのいずれかを変更することを忘れた場合、データはもはや正しくなくなり、役に立たなくなります。これは重要なステップです。

特に複雑なデータのテストケースを選んで、関連する各テーブルに1つ以上のテストケースを含めるようにしてください。既存の値を作業表に保管します。

移行を開始するには、古いテーブルのselectを使用して新しいテーブルに挿入します。レコードの量によっては、パフォーマンスを向上させるために、一度に1レコードではなく、バッチをループすることができます。新しいキーがIDの場合は、古いキーの値をそのフィールドに置き、データベースに新しいキーを作成させるだけです。

次に、関連する表と同じ操作を行います。その後のようなもので、外部キーフィールドを更新するために、テーブル内の古いキー値を使用します。

Update t2 
set fkfield = newkey 
from table2 t2 
join table1 t1 on t1.oldkey = t2.fkfield 

テストケースを実行すると、あなたは、移行前から保存されたものとのデータを比較することで、あなたの移行をテストします。移行データを徹底的にテストすることは非常に重要ですが、データが古い構造と一貫しているかどうかを確認することはできません。移行は非常に複雑な動作です。それはあなたの時間を費やして、非常に体系的かつ徹底的にそれを支払うことを支払う。

0

私の知る限り、あなたはしかし、あなたが何をしたいかを達成するためにトリガーを使用することができ、単一のSQLステートメント

を持つ2つの異なるテーブルを更新することはできません。

2

私が知っている最高のことはoutput clauseです。 SQL 2005または2008があると仮定します。

USE AdventureWorks; 
GO 
DECLARE @MyTableVar table(ScrapReasonID smallint, 
          Name varchar(50), 
          ModifiedDate datetime); 
INSERT Production.ScrapReason 
    OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate 
     INTO @MyTableVar 
VALUES (N'Operator error', GETDATE()); 

元のテーブルを更新するには2番目のパスが必要です。ただし、ロジックを簡単にするのに役立ちます。ソーステーブルを更新する必要がありますか?新しいIDを第3の相互参照表に格納するだけで済みます。

1

Heh。私は移行でこれをやっていることを覚えています

old_idを新しいテーブルに置くと、更新が簡単になります。insert into newtable select ... from oldtableを実行するだけで、レコードの後続の「スティッチング」が容易になります。 「ステッチ」では、新しい親(insert into newchild select ... (select id from new_parent where old_id = oldchild.fk) as fk, ... from oldchild)で副選択を行うことによって、挿入内の子テーブルの外部キーを更新するか、子を挿入して外部キーを修正する別の更新を行います。

1つのインサートで行う方が高速です。別のステップでそれを実行すると、インサートがオーダー依存ではなく、必要に応じて再実行できます。

移行後に、old_id列を削除するか、レガシーシステムでIDが公開され、ユーザーがキーをデータとして使用した場合は、そのIDに基づいて使用参照を許可することができます。 old_id。

実際に、外部キーが正しく定義されている場合は、systables/information-schemaを使用して挿入文を生成できます。

4

おそらく最も簡単な方法は、oldIdのMV6.Postsに列を追加し、古いテーブルのすべてのレコードを新しいテーブルに挿入することです。あなたがクリーンアップ、あなたがしたい場合は、その後oldId列を削除でき

UPDATE mv5.posts 
SET newid = n.id 
FROM mv5.posts o, mv6.posts n 
WHERE o.id = n.oldid 

:最後に、のようなもので、新しいテーブルでoldId上の古いテーブルマッチングを更新します。

+0

私は実際には、新しいテーブルにoldIdを残す方が古いテーブルにnewIdを持つ方が望ましいと考えています。 – ninesided

0

MV6.Post.OldMV5Id

の列がMV6.Postに インサートが、MV5.Postの更新を行い、その後MV5.Post

から...選択 作ることを確認します。MV6ID

1

この更新をINSERT INTO SELECT FROMで行う方法はありますか?手動ですべてのレコードを処理する必要はありませんか?

あなたはそれが手動が、自動的に、あなたがMV6.Postsに挿入したときUPDATEが自動的MV5.Postsに起こるようMV6.Postsにトリガーを作成行うにはなりたくないので。

そして、あなたのトリガが何かのように見えるかもしれませんが、移行と

create trigger trg_MV6Posts 
on MV6.Posts 
after insert 
as 
begin 
    set identity_insert MV5.Posts on 

    update MV5.Posts 
    set ID = I.ID 
    from inserted I 

    set identity_insert MV5.Posts off 
end 
関連する問題