2012-02-08 44 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