1

古いDBの親テーブルと子テーブルから新しいDBの同様のテーブルにデータを移行したいと思います。古いスキーマと新しいスキーマは異なります。

古いDBでは、親エントリには(ID、...)があり、子エントリにはそれぞれ(ID、pid、...)があります。ここで、pidは対応する親行のIDです。

問題は、宛先DBでそれらを接続するにはどうすればよいですか?私は立ち往生しています。その方法は、要素ごとにoldIDをnewIDにマップするテーブルを作成することだと思っていました。ただし、トリガー、出力句、または私が見た他のいずれかを使用してそれを行う方法を理解することはできません。

他にも移行したいテーブルがあるので、oldIDからnewIDへのマッピングテーブルが便利です。より良い解決策がない限り。

さらに説明すると...古いDBには、新しいDBに保持する必要のある外部キー関係があります。ただし、行が新しいDBにコピーされると、新しいPKが取得されます。子テーブルの行には、FKとして親行の古いPKがあります。古いDBから新しい行に子行をコピーするには、親の古いPKを持つ古いDBから子行を選択する必要がありますが、親の新しいPKを持つ新しいDBに挿入します。それは私がSQLでどうやってやるのか理解できない部分です。

ありがとう、エリック

4

3 に答える 3

1

古いDBからのSELECTを使用して、新しいDBのINSERTクエリを作成することはできませんか?

このようなものが機能するはずです:

INSERT INTO NewDB.schema.TableName (newCol1, newCol2, ... ,newColN)
SELECT oldCol1, oldCol2, ... , oldColN 
FROM OldDB.schema.TableName

また、 ApexSQLDataDiffやSQLDataCompareなどのハイエンドのデータ比較ツール、これを自動的に実行できる、ある種の高度なテーブルマッピングを提供していると思います。このためにこれらのツールが必要だとは思いませんが、役立つかもしれません。

于 2013-02-13T14:33:47.540 に答える
0

OK私には解決策があります。ただし、そのようにコード化されているようです。とにかく、次のループが実行された後、fidToGroupIdテーブルは古いDBIDを新しいDBIDにマップできます。これで、FKが以前のファミリーIDを指していたファミリーメンバーを、JOINを使用して新しいグループIDにマップし、新しいDBに挿入できるようになりました。

私は、このように列をすりつぶすよりも、よりエレガントな(そして面倒ではない!)解決策があることを望んでいました。

use phdb 

declare @GroupId int
declare @UserId int
declare @ClientId char( 11 )

select @ClientId = min( ID ) from mcndb.dbo.tClient where IsPerson=0
while @ClientId is not null
begin
    -- Old.Family becomes New.Group
    insert into Groups (GroupName, GroupKind)
        select (fname + ' ' + lname) as GroupName, 'Family' 
            from mcndb.dbo.tClient where ID = @ClientId
    set @GroupId = SCOPE_IDENTITY()

    -- Map fid to GroupId for later use
    insert into mcndb.dbo.fidToGroupId (fid, GroupId)
    values (@ClientId, @GroupId)

    -- Create a user for parent of the family group 
    insert into Users (FirstName, LastName, IsFemale, DoB, ProviderUserKey)
        select fname, lname, 0, '1977-07-07', '00000000-0000-0000-0000-000000000000'
            from mcndb.dbo.tClient where ID = @ClientId 
    set @UserId = SCOPE_IDENTITY()

    -- Connect the parent into the group
    insert into UsersInGroups (Group_ID, [User_ID], [Role])
        values (@GroupId, @UserId, 'PayingParent')

    -- Next row
    select @ClientId = min( id ) from mcndb.dbo.tClient 
        where ID > @ClientId and IsPerson = 0
end
于 2013-02-14T21:10:36.803 に答える
0

別のアプローチは次のとおりです。

ターゲットデータベーステーブルに列を追加IDMapし、への結合に基づいて関連テーブルを挿入するだけIDMapです。

例:テーブルの場合

CREATE TABLE db1.dbo.Parent
(
  Id int identity,
  description varchar(max),
  PRIMARY KEY(Id)
)

CREATE TABLE db1.dbo.Child
(
  Id int identity,
  ParentId int NOT NULL,
  SomeChar char(1),
  PRIMARY KEY(Id),
  FOREIGN KEY(ParentId) REFERENCES db1.dbo.Parent(Id)
)

CREATE TABLE db2.dbo.Parent
(
  Id int identity,
  description varchar(max),
  PRIMARY KEY(Id)
)

CREATE TABLE db2.dbo.Child
(
  Id int identity,
  ParentId int NOT NULL,
  SomeChar char(1),
  PRIMARY KEY(Id),
  FOREIGN KEY(ParentId) REFERENCES db2.dbo.Parent(Id)
)

インポートスクリプトは次のようになります。

ALTER TABLE db2.dbo.Parent ADD IDMap INT
--might consider adding an index for performance, might help, might hurt.
GO

INSERT INTO db2.dbo.Parent (description, IDMap)
SELECT description, Id FROM db1.dbo.Parent

INSERT INTO db2.dbo.Child (ParentId, SomeChar)
SELECT db2.dbo.Parent.Id, db1.dbo.Child.SomeChar
FROM db1.dbo.Child
INNER JOIN db2.dbo.Parent ON db2.dbo.Parent.IDMap = db1.dbo.Child.ParentId

これが上記を示すSQLフィドルです(SQLフィドルの制限のために厳密に言えばクロスデータベースではありませんが、あなたにアイデアを与えるはずです)。

IDMapその後、列をドロップするか、後世のために残しておくことができます。

于 2013-02-15T05:44:42.303 に答える