2014-10-05 48 views
0

任何想法我在這裏做錯了嗎?postgresql光標「進入」循環不返回任何數據

CREATE OR REPLACE FUNCTION update_prices_in_ord1() RETURNS void AS $$ 
DECLARE 
    cur CURSOR for select ord2.ord1_id, sum(ord2.price*ord2.qty) as totprice from ord2 group by ord1_id; 
    --tmpid int; 
    --tmpid ord2.ord1_id%TYPE; 
    --tmpprice float; 
    mydata RECORD; 
BEGIN 
    open cur; 
    loop 
    --fetch cur into tmpid,tmpprice; 
    fetch cur into mydata; 
    --raise notice 'price=%, id=%', tmpprice, tmpid; 
    raise notice 'price=%, id=%', mydata.totprice, mydata.ord1_id; 
    update ord1 set price=mydata.totprice where id=mydata.ord1_id; 
    end loop; 
    close cur; 
END; 
$$ LANGUAGE plpgsql; 

正如你可以看到我已經嘗試了幾個選項(在評論中),但沒有運氣。 我得到的是無限的空值:

NOTICE: price=<NULL>, id=<NULL> 

如果我單獨運行光標的SQL運行良好:

testdb=# select ord2.ord1_id, sum(ord2.price*ord2.qty) as totprice from ord2 group by ord1_id; 
ord1_id | totprice 
---------+---------- 
     14 |  10 
     27 |  42.5 
     17 |  57.5 
     28 |  43 
     15 |  142 
... 

所有我想要做的就是更新ord1.price場的基礎上,高於總價格,匹配ord1.id.

非常感謝!

回答

1

你已經寫了一個無條件循環。由於沒有exitreturn聲明,它永遠不會停止。

A for loop負責爲您服務。最重要的是,它會打開,從獲取,並自動關閉遊標:

BEGIN 
    for mydata in cur loop 
    raise notice 'price=%, id=%', mydata.totprice, mydata.ord1_id; 
    update ord1 set price=mydata.totprice where id=mydata.ord1_id; 
    end loop; 
END; 

你並不需要一個循環做到這一點,雖然,你應該能夠在普通的SQL來寫這個update

update ord1 
set price = total.totprice 
from (select ord1_id, sum(price*qty) as totprice from ord2 group by ord1_id) total 
where ord1.id = total.ord1_id 
+0

權,其實它是:更新ord1 ...其中ord1.id = total.ord1_id;基本上我的原始代碼也工作,只要我添加「退出時沒有找到;」取回後。 (否則數據仍然會被更新,但函數會永遠循環 - 這就是爲什麼我看到「無限的空值」 - 如果我查找了第一次提高輸出,我會看到它不會是「空值」而且它實際上是「工作」。)非常感謝! – ilias 2014-10-05 08:42:14

+0

糟糕...固定;) – 2014-10-05 10:58:07