2012-09-28 69 views
-1

這裏的問題很簡單(雖然我準備好了答案不是),但我怎樣才能使這個查詢更有效率。好於遊標tsql

簡而言之,它複製記錄。它選擇X條記錄,然後使用這些記錄數據複製它們捕獲新的標識符。使用原始記錄和新記錄的ID,然後通過使用新標識符將原始數據的數據複製到另一個表中進行插入。

這需要很長時間。你能幫助縮短它嗎?

DECLARE DaysToDuplicateCursor CURSOR FAST_FORWARD FOR 
SELECT 
    DayId 
FROM [Days] 
WHERE AgentId IN ('XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX') 
AND PersonAgentId IN (
    'YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY' 
    ,'WWWWWWWW-WWWW-WWWW-WWWW-WWWWWWWWWWWW' 
    ,'ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ' 
    ,'TTTTTTTT-TTTT-TTTT-TTTT-TTTTTTTTTTTT' 
) 

DECLARE @Id INT 

OPEN DaysToDuplicateCursor 
    FETCH NEXT FROM DaysToDuplicateCursor INTO @Id 
    WHILE @@FETCH_STATUS = 0 
    BEGIN 
     -- 
     -- Insert Days data. 
     -- 
     INSERT INTO [Days] (
       [DayTemplateId] 
       ,[DayDate] 
     ) 
     SELECT [DayTemplateId] 
       ,DATEADD(YEAR,-1,[DayDate]) AS [DayDate] 
      FROM [Days] WHERE [DayId] = @Id 
     -- 
     -- Insert Periods data. 
     -- 
     INSERT INTO [Periods] (
      [DayId] 
      ,[PeriodTemplateId] 
     ) 
     SELECT 
      SCOPE_IDENTITY() 
      ,[PeriodTemplateId] 
     FROM [Periods] WHERE [DayId] = @Id 
     -- 
    END 
CLOSE DaysToDuplicateCursor 
DEALLOCATE DaysToDuplicateCursor 
+2

您使用的是哪個版本的Sql Server? –

+0

你想要多少效率?光標本身是否緩慢? AgentId和/或PersonsAgentId上是否有索引?所有涉及的表有多少行? – rene

+0

「WHILE ... BEGIN」塊的'END'關鍵字之前缺少'DaysCHDTO FROM DaysToDuplicateCursor INTO @ Id'導致速度問題。也就是說,我的原始示例中TSQL不正確,直到發佈後才注意到。一旦修改(包括此處提及的添加),查詢就會在預期的毫秒內運行。感謝大家的意見! – user1707012

回答

1

如果使用OUTPUT子句而不是詢問scope_identity,則根本不需要使用遊標。你會把這些信息放在一張可變表中。您還需要返回output子句中唯一標識記錄的其他列,以便您可以在連接中使用它們以獲取後續插入中所需的數據。

+0

這不是一個答案 - 你沒有看過查詢足夠長的時間。這並不是那麼無關緊要,因爲這兩個插頁之間有相關性。在第二次插入中使用的@id不容易從第一次使用OUTPUT派生。 – RichardTheKiwi

+0

如果向表中添加另一列,則可以將id1插入到id2行中。在那一點上,我認爲你可以使用OUTPUT爲新插入的行導出兩個值;一個用於id1,然後是id2。 如果失敗了,您現在有行,您知道a)該行是您的進程創建的,並且b)哪一行是該進程的原始行。 – lyrisey