2016-01-20 42 views
0

我在SQL服務器中的遊標循環出現問題。我試圖從上次迭代中獲取兩個變量,並在下一次迭代中使用它。這是我的查詢:從MSSQL光標中提取兩個變量的最後一個值LOOP

DECLARE @goodid int; 
DECLARE goodIDCursor CURSOR FOR 
SELECT DISTINCT GoodID from Operations 
OPEN goodIDCursor 

FETCH NEXT FROM goodIDCursor INTO @goodid 
WHILE @@FETCH_STATUS = 0 
BEGIN 

    DECLARE @date varchar(20); 
    DECLARE @qtty float; 
    DECLARE @pricein float; 
    DECLARE @qtty1 float; 
    SET @qtty1 = 0; 
    DECLARE @pricein1 float; 
    SET @pricein1 = 0; 
    DECLARE dateCursor CURSOR FOR 
    SELECT DISTINCT Date from Operations where GoodID = @goodid ORDER BY Date 
    OPEN dateCursor 

    FETCH NEXT FROM dateCursor INTO @date 
    WHILE @@FETCH_STATUS = 0 
     BEGIN 

     SET @qtty = (SELECT SUM(Qtty) from Operations WHERE Date = @date and GoodID = @goodid and Sign = 1 AND OperType NOT IN (7,8,15,16,17,18,20,21,22,23,25,33,35,36)); 

     SET @pricein = (SELECT (SUM(Qtty*PriceIn))/SUM(Qtty) from Operations WHERE Date = @date and GoodID = @goodid and Sign = 1 AND OperType NOT IN (7,8,15,16,17,18,20,21,22,23,25,33,35,36)); 

     UPDATE Operations SET PriceIn = ((@qtty1*@pricein1) + (@qtty*@pricein))/(@[email protected]) WHERE GoodID = @goodid and Date = @date and Sign = -1 AND OperType NOT IN (7,8,15,16,17,18,20,21,22,23,25,33,35,36); 

     SET @pricein1 = ((@qtty1*@pricein1) + (@qtty*@pricein))/(@[email protected]); 
     SET @qtty1 = @qtty1 + (SELECT SUM(Qtty*Sign) FROM Operations WHERE Date = @date and GoodID = @goodid); 


    FETCH NEXT FROM dateCursor 
    INTO @date 
    END 
    CLOSE dateCursor 
    DEALLOCATE dateCursor 

FETCH NEXT FROM goodIDCursor 
INTO @goodid 
END 
CLOSE goodIDCursor 
DEALLOCATE goodIDCursor 

所以,從所有這些事情,在這裏應該在第二循環中發生的事情是這樣的: 在我想要的變量@ qtty1和@ pricein1開始爲0後,德第一循環他們應該成爲:

@pricein1 = ((@qtty1*@pricein1) + (@qtty*@pricein))/(@[email protected]); 
@qtty1 = @qtty1 + (SELECT SUM(Qtty*Sign) FROM Operations WHERE Date = @date and GoodID = @goodid); 

,他們必須爲下一次迭代等訪問。每次迭代時,它們的值都將根據之前的計算進行更改,並用於下一次迭代。

+6

你真正需要做的是完全擺脫這個嵌套遊標的概念更新。這可以並應該完全重寫爲基於單個集合的更新。 –

+0

如果你想添加樣例記錄和預期的輸出到你的問題中,我們可能會幫助你擺脫遊標,這在SQL中可能會很慢。如果*必須*保留光標,那麼聽起來您需要將光標B移到光標A中。請參閱[MSDN]上的此頁面底部附近的示例B(https://msdn.microsoft.com/zh-cn/zh-cn/庫/ ms180169.aspx)。但要注意,你錯過了SQL的真正力量。 –

+0

我不能堅持遊標。我會給你一些樣品數據要清楚。 – intenZive

回答

0

處理學術你的問題,並假設我正確理解你的問題,你可以用一個循環計數變量解決這個問題,並且只設置變量時,循環計數器1

內環之前:

DECLARE @LC int = 1; 

在內部循環:

IF @LC = 1 
BEGIN 
SET @pricein1 = ((@qtty1*@pricein1) + (@qtty*@pricein))/(@[email protected]); 
SET @qtty1 = @qtty1 + (SELECT SUM(Qtty*Sign) FROM Operations WHERE Date = @date and GoodID = @goodid); 
END 

內環結束前右:

SET @LC = LC + 1; 

因此,對於外部循環的每次迭代,您將爲內部循環的第一次迭代設置這兩個變量,然後它們將保持不變,直到外部循環的下一次迭代。

如果那不是你所追求的,那麼你的問題就不清楚了。

相關問題