Функция PostgreSQL - PullRequest
       12

Функция PostgreSQL

1 голос
/ 08 февраля 2012

Я создал эту функцию для повторного упорядочения порядкового номера в таблице спецификации (bomitem).

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;

так, чтобы он повторял всю таблицу спецификации.

1 Ответ

1 голос
/ 08 февраля 2012

То, что вы пытаетесь сделать, намного проще с 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.1 для 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.4 для оконной функции row_number().

...