Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# TSQL:使用“插入”更新到“选择自”_C#_Sql_Tsql_Migration_Bulkinsert - Fatal编程技术网

C# TSQL:使用“插入”更新到“选择自”

C# TSQL:使用“插入”更新到“选择自”,c#,sql,tsql,migration,bulkinsert,C#,Sql,Tsql,Migration,Bulkinsert,所以我有一个旧的数据库,我正在迁移到一个新的。新的模式略有不同,但基本上是兼容的。另外,我想从零开始对所有表重新编号 目前,我一直在使用我编写的工具,手动检索旧记录,将其插入新数据库,并更新旧数据库中的v2id字段,以显示其在新数据库中的相应ID位置 例如,我从MV5.Posts中选择并插入到MV6.Posts中。插入后,我在MV6.Posts中检索新行的ID,并在旧的MV5.Posts.MV6ID字段中更新它 有没有一种方法可以通过插入选择来进行更新,这样我就不必手动处理每条记录?我使用的是S

所以我有一个旧的数据库,我正在迁移到一个新的。新的模式略有不同,但基本上是兼容的。另外,我想从零开始对所有表重新编号

目前,我一直在使用我编写的工具,手动检索旧记录,将其插入新数据库,并更新旧数据库中的v2id字段,以显示其在新数据库中的相应ID位置

例如,我从MV5.Posts中选择并插入到MV6.Posts中。插入后,我在MV6.Posts中检索新行的ID,并在旧的MV5.Posts.MV6ID字段中更新它


有没有一种方法可以通过插入选择来进行更新,这样我就不必手动处理每条记录?我使用的是SQL Server 2005开发版。

好的,您不能用一条SQL语句更新两个不同的表


但是,您可以使用触发器来实现您想要做的事情。

据我所知,您最好使用触发器。假设您有SQL2005或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());

它仍然需要第二次传递来更新原始表;然而,它可能会帮助您简化逻辑。是否需要更新源表?您可以将新id存储在第三个交叉引用表中

嘿。我记得在迁移中这样做过

将旧的_id放在新表中可以使更新更容易-您只需在newtable select中插入即可。。。从oldtable,-和后续的记录缝合更容易。在stitch中,您可以在insert中更新子表的外键,方法是对新父表insert执行子选择,然后将其插入到newchild select中。。。从新父项中选择id,其中旧id=oldchild.fk作为fk。。。从oldchild或您将插入子项并执行单独的更新以修复外键

在一次插入中执行此操作速度更快;在单独的步骤中执行这一操作意味着您的插入不依赖于顺序,并且可以在必要时重新执行

迁移后,您可以删除旧的\u id列,或者,如果旧系统公开了id,因此用户将密钥用作数据,则可以保留它们以允许基于旧的\u id进行使用查找


实际上,如果外键定义正确,可以使用systables/information schema生成insert语句。

最简单的方法可能是在MV6.Posts上为oldId添加一列,然后将旧表中的所有记录插入到新表中。最后,使用以下内容更新新表中与oldId匹配的旧表:

UPDATE mv5.posts
SET newid = n.id
FROM mv5.posts o, mv6.posts n 
WHERE o.id = n.oldid
Update t2
set fkfield = newkey
from table2 t2
join table1 t1 on t1.oldkey = t2.fkfield

如果愿意,您可以在以后清理并删除oldId列。

在MV6.Post.OldMV5Id中创建一列

制造 插入MV6.Post 选择来自MV5.Post

然后更新MV5.Post.MV6ID

有没有一种方法可以通过插入选择来进行更新,这样我就不必手动处理每条记录

因为您不希望手动执行,而是自动执行,所以请在MV6.Posts上创建一个触发器,以便在插入到MV6.Posts时在MV5.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

迁移的关键是要做几件事: 首先,在没有当前备份的情况下,不要做任何事情。 第二,如果密钥将要更改,那么如果密钥字段向用户公开,您需要在新结构中至少暂时永久地存储新旧密钥,因为用户可能正在通过它进行搜索以获取旧记录

接下来,您需要彻底了解与子表的关系。如果更改键字段,则所有相关表也必须更改。这就是存储新旧钥匙的方便之处。如果您忘记更改其中任何一个,数据将不再正确,并且将毫无用处。所以这是关键的一步

挑选一些特别复杂数据的测试用例,确保为每个相关表包含一个或多个测试用例。将现有值存储在工作表中

要开始迁移,请使用“从旧表中选择”命令插入到新表中。根据记录的数量,您可能希望一次循环批处理而不是一条记录以提高性能。如果新密钥是一个标识,只需将旧密钥的值放入其字段中,并让数据库创建新密钥

然后对相关表执行相同的操作。然后使用表中的旧键值更新外键字段,如下所示:

UPDATE mv5.posts
SET newid = n.id
FROM mv5.posts o, mv6.posts n 
WHERE o.id = n.oldid
Update t2
set fkfield = newkey
from table2 t2
join table1 t1 on t1.oldkey = t2.fkfield

通过运行测试用例并将数据与迁移前存储的数据进行比较来测试迁移。彻底测试迁移数据至关重要,否则您无法确保数据与旧结构一致。移徙是一项非常复杂的行动;花点时间,有条不紊、彻底地去做是值得的

事实上,我认为把旧ID放在新表上比在旧表上放一个新ID更好,这使得这更容易。