2017-03-09 59 views
0

我想通過使用以下過程來更新列,它使用LAG函數,因爲結果是通過將前一個值減去目前的價值,因爲它可以在下面的圖片中看到,但它不工作,因爲它填充我不期望的值的col3 ..更新基於其他兩列和使用LAG函數的Oracle過程中的列

基本上我想要的是(使用Excel來說明問題):

Description table

而且我想這對錶中的每一個不同的名稱。

create or replace procedure proc1 as 
    cursor cur is 
    SELECT (col1 - LAG(col1,1) OVER (PARTITION BY name order by ID)) 
    FROM table1 
    for update; 
    var_diff NUMBER; 
begin 
    open cur; 
    loop 
    fetch cur into var_diff; 
    exit when cur%NOTFOUND; 
    update table1 set col3=var_diff where current of cur; 
    end loop; 
    close cur; 
end proc1; 
/

exec proc1; 
commit; 

我知道的例子,上面使用的SQL語句的工作:

SELECT col1, 
     LAG(col1,1) OVER (PARTITION BY name order by ID), 
     (col1 - LAG(col1,1) OVER (PARTITION BY name order by ID)) 
FROM table1; 

但我不能使程序工作。

+1

其中C_F的電流;?爲什麼你使用c_f?它不應該是你的光標名嗎? –

+1

我測試了你的代碼。除了窗口第一行中的「col3」爲空而不是「col1」的當前值之外,它會生成Excel截屏中顯示的結果。這很容易用'nvl()'或其他東西解決。如果你認爲你的問題比你需要發佈一個*完整的*(但很小)的可重複測試用例更廣泛。 – APC

+1

您可以在proc中逐行更新表格行,但這是一個緩慢的選項。有人說,逐行=緩慢。你可以完全用SQL來完成。你可能正在測試/試圖學習pl/sql,這很好,只要明白這不是做你正在做的事情的最好方法。 – unleashed

回答

1

我覺得這隻能通過SQL輕鬆完成。如果可能的話,我們應該/必須總是嘗試通過SQL方法解決問題,然後在需要時查找PLSQL選項。這個要求可以通過MERGE或簡單的UPDATE語句輕鬆完成。我已經說明了PLSQL ND sql方式。希望這可以幫助。

--SQL Way better then PLSQL way 
merge INTO TABLE1 tab USING 
(SELECT (COL1 - LAG(COL1,1) over (partition BY name order by id)) COL1 
FROM TABLE1 
)a ON (TAB.COL1 = a.COL1) 
WHEN matched THEN 
    UPDATE SET COL3 = a.COL1 WHERE col1 = a.col1; 

--PLSQL way but will be slow as we are doing it row-row aka slow-by-slow provcessing 
CREATE OR REPLACE 
PROCEDURE proc1 
AS 
BEGIN 
    for I  in 
    (SELECT (COL1 - LAG(COL1,1) over (partition BY name order by id)) col3,col1 
    FROM table1 
) 
    LOOP 
    UPDATE table1 SET col3=i.col3 where col1 = i.col1; 
    END LOOP; 
END proc1; 
+0

它通過查看你的工作,但我不得不做一些調整。見下文。 –

0

最後,下面其他的建議,這個SQL語句工作對我來說:

MERGE INTO TABLE1 tab 
    USING (SELECT ID,(NVL(COL1,0) - NVL(LAG(NVL(COL1,0),1) OVER (PARTITION BY NAME order by ID),0)) VAL FROM TABLE1) a 
    ON (tab.ID = a.ID) 
    WHEN matched THEN 
     UPDATE SET tab.COL3 = a.VAL;