我在C#中创建了一个函数,它允许我将记录及其相关的子项复制到同一数据库中的新记录和新的相关子项。 (这适用于允许将以前的工作用作新工作模板的应用程序。)
无论如何,它的效果很好......以下是它如何完成复制的描述:
它使用每条记录的当前主键填充基于内存的两列查找表。接下来,当它单独创建每个新的复制记录时,它会使用新记录的标识PK [从SCOPE_IDENTITY()检索]更新查找表。现在,当它复制任何相关的子节点时,它可以查找新的父PK以在新记录上设置FK。
在测试中,只花了一分钟时间在SQL Server 2005 Express Edition的本地实例上复制关系结构。不幸的是,它的生产速度非常慢!我的用户正在通过LAN向我们的SQL Server处理每条父记录60,000多条记录!虽然我的复制功能仍然有效,但每个记录都代表一个单独的SQL UPDATE命令,它将SQL Server从正常的2%空闲状态加载到大约17%的CPU。我刚刚完成了50,000个记录副本的测试,花了差不多20分钟!
有没有办法在SQL查询或存储过程中复制此功能,以使SQL服务器完成所有复制工作,而不是从每个客户端通过LAN进行爆破?
(我们正在运行Microsoft SQL Server 2005标准版。)
谢谢!
-Derek
答案 0 :(得分:1)
是的,如果它是SQL 2005,您可以使用CLR存储过程将C#代码安装到Db中。要做到纯粹的TSQL,这只是一个繁琐而且需要为新密钥使用变量的问题。这只是一个父记录的案例,然后是一个只在一个子表中的很多子记录吗?在这种情况下,您可以通过利用可以将select语句嵌入到插入中的事实来避免为每个子行发出单独的插入命令,尤其是在您使用PK的标识列时。如果你能做到这一点,通常会更快。 像这样的东西(语法可能有点偏,但无论如何你都需要适应你的真实表格):
insert into tblchild select @newparentId, col1,col2 from tblChild where parentid=@oldparentid
以下是SQL Server中CLR的起点......
http://msdn.microsoft.com/en-us/library/ms131045.aspx(本文是SQL 2008,但其中大部分可能适用)。
http://www.sqlteam.com/article/writing-clr-stored-procedures-in-charp-introduction-to-charp-part-1
答案 1 :(得分:0)
会使用(伪代码)
INSERT INTO (PkField, FkField, OtherFields) SELECT NewPkValue, NewFkValue, OtherFields FROM TableName WHERE FkField = OldFkValue
帮助相关子表,因为它们将被批处理而不是每个记录单个更新?