Sql 无法将两个表从一个数据库迁移到另一个数据库

Sql 无法将两个表从一个数据库迁移到另一个数据库,sql,sql-server,migration,Sql,Sql Server,Migration,我正在尝试将一些数据从旧数据库中的两个表迁移到新数据库 问题是,我希望在新数据库中为要导入的第一个表生成新的主键。这很简单 但是旧数据库中的第二个表与第一个表有外键依赖关系。因此,当我想从第二个表迁移旧数据时,外键不再匹配 是否有任何技巧/最佳实践可以帮助我迁移数据 严重注意:我无法更改新表的当前模式,因为这些表没有任何“旧id”列 让我们使用下表架构:- Old Table1 New Table1 ParentId INT PK ParentId IN

我正在尝试将一些数据从旧数据库中的两个表迁移到新数据库

问题是,我希望在新数据库中为要导入的第一个表生成新的主键。这很简单

但是旧数据库中的第二个表与第一个表有外键依赖关系。因此,当我想从第二个表迁移旧数据时,外键不再匹配

是否有任何技巧/最佳实践可以帮助我迁移数据

严重注意:我无法更改新表的当前模式,因为这些表没有任何“旧id”列

让我们使用下表架构:-

Old Table1              New Table1
ParentId INT PK         ParentId INT PK
Name VARCHAR(50)        Name VARCHAR(50)

Old Table 2             New Table 2
ChildId INT PK          ChildId INT PK
ParentId INT FK         ParentId INT FK     
Foo VARCHAR(50)         Foo VARCHAR(50)
因此,表模式是相同的

想法

编辑:
对于那些提出要求的人来说,RDBMS是Sql Server 2008。我没有指定软件,因为我希望用一些通用的t-Sql得到一个不可知的答案:P你能更改旧表的模式吗?如果是这样,您可以在旧表上放置一个“newid”列,并将其用作引用


您可能需要在新表上逐行插入,然后检索scope_标识,并将其存储在旧表1中。但是对于表2,您可以加入旧的表1并获取新的id。

我认为您需要分两个步骤来完成这项工作

您需要导入旧表并保留旧ID(并生成新ID)。然后,一旦它们在新数据库中,并且它们具有新Id和旧Id,您就可以使用旧Id来关联新Id,然后删除旧Id

您可以通过导入到临时表(即,它们将被丢弃)中,然后插入到永久表中,省去旧ID来实现这一点

或者将directy导入到新表中(将模式修改为也保存旧id),然后在不再需要旧id时删除它们

编辑:

好的,由于这里的评论和其他答案,我对你要找的东西更清楚了一点。我搞砸了,我想它会满足你的要求

基本上没有游标,它逐行遍历父表,插入新的partent行以及父行的所有子行,保持新id的同步。 我试过了,它应该可以工作,它不需要对表的独占访问,应该比游标快几个数量级

declare @oldId as int
declare @newId as int

select @oldId = Min(ParentId) from OldTable1 

while not @oldId is null
begin
    Insert Into NewTable1 (Name)
    Select Name from OldTable1 where ParentId = @oldId

    Select @newId = SCOPE_IDENTITY()

    Insert Into NewTable2 (ParentId, Foo)
    Select @newId, Foo From OldTable2 Where ParentId = @oldId

    select @oldId = Min(ParentId) from OldTable1 where ParentId > @oldId

end

希望这会有所帮助,

好吧,我想您必须确定其他标准来创建像oldPK=>newPK这样的映射(例如:
Name
字段是否相等

然后,您可以确定与旧PK匹配的新PK,并相应地调整
ParentID

您还可以做一个小技巧:在原始表1中添加一个新列,该列存储复制记录的新PK值。然后您可以轻松复制表2的值,将它们指向新列的值,而不是旧PK

编辑:我试图提供一些示例代码来说明我的小技巧。我不是在改变原始数据库结构,而是在使用一个临时表

好的,您可以尝试以下操作:

1) 创建包含旧表的值的临时表,另外,它将获得一个新的PK:

CREATE TABLE #tempTable1
(
    newPKField INT,
    oldPKField INT,
    Name VARCHAR(50)
)
2) 将旧表中的所有值插入临时表,计算新PK,复制旧PK:

INSERT INTO #tempTable1
SELECT
   newPKValueHere AS newPKField,
   ParentID as oldPKField,
   Name
FROM
   Table1
3) 将值复制到新表中

INSERT INTO NewTable1
SELECT
   newPKField as ParentId,
   Name
FROM
   #tempTable1
4) 将表2中的值复制到新表2中

INSERT INTO NewTable2
SELECT
   ChildID,
   t.newPKField AS ParentId,
   Foo
FROM 
   Table2
   INNER JOIN #tempTable1 t ON t.ParentId = parentId

这应该可以。请注意,这只是伪T-SQL代码——我还没有在真正的数据库上测试过它!然而,它应该接近您所需要的。

首先,您甚至不能有一些临时模式,以后可以删除吗?!那会让生活更轻松。假设你不能:

如果幸运的话(如果您能保证不会同时发生其他插入),那么当您将Table1的数据插入到新表中时,您可能会依靠插入的顺序作弊


然后,您可以创建一个视图,将两个表按行计数连接起来,这样您就可以将键相互关联起来。这样,您就更接近于能够识别新表2的“ParentId”。

我不确定您使用的是什么数据库软件,但如果临时表是一个选项,请创建一个临时表,其中包含表1的原始主键和表1的新主键。然后使用table2的副本创建另一个临时表,使用先前创建的“旧键,新键”表更新副本,然后使用“插入到select from”(或适用于数据库的任何适当命令)将修改后的临时表复制到其永久位置。

去年夏天,我有一个极好的机会深入研究迁移脚本。我使用Oracle的PL/SQL来完成这项任务。但是你没有提到你在使用什么技术?您要将数据迁移到什么位置?SQL Server?神谕MySQL


这种方法是从表1插入一行,返回新的主键(可能是由[Oracle中的]序列生成的),然后从表2中插入依赖记录,将其外键值更改为第一次插入返回的值。除非您能指定要将数据迁移到哪个DBMS,否则无法提供更好的帮助。

以下伪ish代码应该适合您

CREATE TABLE newtable1
  ParentId INT PK
  OldId   INT
  Name     VARCHAR(50)

CREATE TABLE newtable2
  ChildId    INT pk
  ParentId   INT FK
  OldParent  INT
  Foo        VARCHAR(50)   

  INSERT INTO newtable1(OldId, Name)
  SELECT  ParentId, Name FROM oldtable1

  INSERT INTO newtable2(OldParent, Foo)
  SELECT ParentId, Foo FROM oldtable2

UPDATE newtable2 SET ParentId = (
  SELECT n.ParentId 
  FROM   newtable1 AS n
  WHERE  n.OldId = newtable2.oldParent
)

ALTER TABLE newtable1 DROP OldId
ALTER TABLE newtable2 DROP OldParent

Name和Foo是唯一的吗?如果是这样的话,你可以加入这些团队,找出旧ID是什么……哪些RDBMS?你用什么方法导入数据?@Pure.Krome:Egads,伙计,我认为你不能在这里绕过游标。我不想这么说,但我认为这是你最好的解决办法。为了您的利益,我只希望您拥有相对较小的数据集。没有问题:)游标很好。这是一次迁移。我会确保它是一个快进光标。我只是好奇窥视者是否还有其他的把戏。干杯伙伴:)我担心我必须用光标来做这件事。I c