2012-02-08 77 views
1

我已經創建了此函數來對BOM表(bomitem)上的序號重新排序。PostgreSQL函數

CREATE OR REPLACE FUNCTION seqincr(integer) 
    RETURNS SETOF bomitem AS 
$BODY$ 
DECLARE 
    pItemid ALIAS FOR $1; 
    _row bomitem%ROWTYPE; 
    seqint int; 
    _id int; 


BEGIN 
    seqint=8; 
    FOR _row IN SELECT * 
      FROM bomitem 
      WHERE ((bomitem_parent_item_id=pItemid)) 
    LOOP 
    RETURN NEXT _row; 
    _id = _row.bomitem_id; 
    seqint = seqint+2; 
    update bomitem set bomitem_seqnumber = seqint where bomitem_id=_id; 
    END LOOP; 

    RETURN; 
END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100 
    ROWS 1000; 
ALTER FUNCTION seqincr(integer) 
    OWNER TO admin; 

的例子適用於個人bomitem_parent_item_id象下面這樣:

SELECT * from seqincr(14917); 

我想改寫這個功能遍歷

SELECT distinct bomitem_parent_item_id FROM bomitem; 

,使其resequences整個BOM表。

回答

1

你所要做的是與CTE更加簡單:

WITH x AS (
    SELECT bomitem_parent_item_id 
     , row_number() OVER (ORDER BY bomitem_parent_item_id) AS rn 
    FROM bomitem 
    GROUP BY bomitem_parent_item_id 
    ORDER BY bomitem_parent_item_id 
    ) 
UPDATE bomitem b 
SET bomitem_seqnumber = 8 + 2 * rn 
FROM x 
WHERE x.bomitem_parent_item_id = b.bomitem_id; 

你至少需要的PostgreSQL 9.1data-modifying CTE

或者使用子查詢,在早期版本的,太:

UPDATE bomitem b 
SET bomitem_seqnumber = 8 + 2 * rn 
FROM (
    SELECT bomitem_parent_item_id 
     , row_number() OVER (ORDER BY bomitem_parent_item_id) AS rn 
    FROM bomitem 
    GROUP BY bomitem_parent_item_id 
    ORDER BY bomitem_parent_item_id 
    ) x 
WHERE x.bomitem_parent_item_id = b.bomitem_id; 

但是,你至少需要的PostgreSQL 8.4window functionrow_number()

+0

對不起,我花了這麼長時間才注意到你的答案。感謝您抽出寶貴的時間。您的解決方案會發生什麼情況,材料清單中的每個組件都獲得相同的bomitem_seqnumber。每個新物料清單都會獲得與組數相對應的下一個更高的整數。我需要的是讓每個bomitem_seqnumber遞增,以便賬單中的第一個組件的bomitem_seqnumber爲10,接下來的12,接下來的14等等。我的功能工作得很好,除了在整個bomitem表中不是迭代的。 – 2012-02-25 01:18:13

+0

嗨,你也許還可以幫助我解決這個問題:https://stackoverflow.com/questions/44318816/function-for-postgresql?noredirect=1#comment75643213_44318816?謝謝 – 2017-06-02 00:08:57