2012-10-02 72 views
0
CREATE OR REPLACE FUNCTION fnMyFunction(recipients recipient[]) ... 

    FOREACH v_recipient IN ARRAY recipients 
     LOOP 
      v_total := v_total + v_recipient.amount; 
      INSERT INTO tmp_recipients(id, amount) 
      VALUES(v_recipient.id, v_recipient.amount::numeric(10,2)); 
    END LOOP; 

... 

這個工作在開發環境很好,但只是發現了釋放的環境是8.4這似乎不支持foreach構造。我希望有人可以通過數組參數集並使用數組中的值以類似的方式揭示循環的替代實現,以避免完整的重構。遍歷數組參數WITHOUT的foreach

我收到的錯誤信息是:

ERROR: syntax error at or near "FOREACH" SQL state: 42601 Context: SQL statement in PL/PgSQL function "fnMyFunction" near line ##

的DB環境是一個共享的主機上,所以我必須對平臺的升級沒有選項。
我標記了postgres 9.1和8.4,因爲該函數在9.x中正常工作,但在8.4上失敗。

回答

2

使用unnest;我認爲這是在8.4。未經測試,但我認爲是正確的:

FOR v_recipient IN SELECT vr FROM unnest(recipients) x(vr) 
LOOP 
.... 
END LOOP; 

如果你不能做到這一點,你會使用索引到數組必須遍歷array_length

+0

因此,它看起來像這樣工作,不幸的是我沒有找到一個不明確的解釋。現在的問題是我似乎獲得了v_recipient元素中的第一項,但不是第二項。收件人元素是基於兩個字段的id和金額我假設結構看起來像這樣︰{{1,1.00},{2,1.00}} – tafaju

+0

剛剛添加x(attr1,attr2)..謝謝克雷格! – tafaju

+0

@tafaju鏈接到「unnest」文檔。 –

1

您擁有它的方式一次執行一個INSERT。對於關係數據庫,基於集合的操作通常比一次一個遍歷記錄的速度快得多。

這應該是更簡單,更快並用的PostgreSQL 8.4或更高版本的工作:

INSERT INTO tmp_recipients(id, amount) 
SELECT (r.col).* 
FROM (SELECT unnest(recipients) AS col) r 

這假定該陣列的複合基類型包括(id, amount) - 的順序 - 和amount類型可以是強制爲numeric(10,2)。否則,或只是可以肯定,更明確:

INSERT INTO tmp_recipients(id, amount) 
SELECT (r.col).id, (r.col).amount::numeric(10,2) 
FROM (SELECT unnest(recipients) AS col) r 

各地(r.col)括號是不可選的。它們需要消除複合類型的語法。