【发布时间】:2011-04-06 12:38:23
【问题描述】:
我正在创建一个 SQL 2008 R2 存储过程来复制一行及其所有子行。
这是一个包含父、子和子子的 3 层设置 给定父母的 ID,我需要创建一个副本。
我已经使用fast_forward cursor 解决了这个问题。
我知道我也可以使用 while 循环遍历行来做到这一点,但我认为这不会比这种游标方法更快。你有什么想法?
有没有更好的方法在不使用光标的情况下完成这项任务?
编辑:我考虑的另一个选项是创建一个临时表,其中包含 TBLACStages 记录的旧/新 PKID。
TBLACStages 可能有 1 到 20 个对应的行(并且 TBLACUpgrade 可能每个 TBLACStages 行有 3 行)
CREATE PROCEDURE [dbo].[spDuplicateACUnit]
@pACUnitID bigint = 0
AS BEGIN
SET NOCOUNT ON;
DECLARE @NewACUnitID bigint = 0
INSERT INTO TBLACUnits ([col1] ,[col2] ,[...] ,[coln]) SELECT [col1] ,[col2] ,[...] ,[coln] FROM TBLACUnits WHERE ACUnitID = @pACUnitID
SELECT @NewACUnitID = SCOPE_IDENTITY()
DECLARE @ACStageID bigint = 0
DECLARE @NewACStageID bigint = 0
DECLARE @ACUnitCursor CURSOR
SET @ACUnitCursor = CURSOR LOCAL FAST_FORWARD FOR SELECT ACStageID FROM TBLACStages WHERE TBLACStages.ACUnitID = @pACUnitID
OPEN @ACUnitCursor
FETCH NEXT FROM @ACUnitCursor INTO @ACStageID
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO TBLACStages ([ACUnitID] ,[col1] ,[col2] ,[...] ,[coln]) SELECT @NewACUnitID ,[col1] ,[col2] ,[...] ,[coln] FROM TBLACStages WHERE TBLACStages.ACStageID = @ACStageID
SELECT @NewACStageID = SCOPE_IDENTITY()
INSERT INTO TBLACUpgrade ([ACStageID] ,[col1] ,[col2] ,[...] ,[coln]) SELECT @NewACStageID ,[col1] ,[col2] ,[...] ,[coln] FROM TBLACUpgrade WHERE TBLACUpgrade.[ACStageID] = @ACStageID
FETCH NEXT FROM @ACUnitCursor INTO @ACStageID
END
CLOSE @ACUnitCursor DEALLOCATE @ACUnitCursor
END
GO
【问题讨论】:
-
对不起,格式看起来很糟糕,复制/粘贴到 SO 中并不容易。
-
除了 ACStageID 之外,TBLACStages 中是否有任何候选键(唯一列)?
-
不,唯一保证唯一的列是 PK,即 ACStageID
-
复合键怎么样(多列组合时是唯一的)
-
除非与 PK 结合使用,否则没有什么是绝对独一无二的。
标签: sql-server tsql cursors fast-forward