在存储过程中使用WITH,postgres

时间:2014-12-11 10:54:31

标签: sql postgresql stored-procedures common-table-expression postgresql-8.4

我正在使用一系列项目在桌面上工作。对于每个项目,都会有一个父项。树结构也是如此。

我需要获取 第1项>>等项目的完整详情。项目1.1>>项目1.1.1>>项目1.1.1.1>>项目1.1.1.1.1 所以我决定创建一个函数,在我们传递项目的id时返回详细信息,在 项目1.1.1.1的示例id中.1

CREATE TABLE item (
    item_id bigint,
    item_name text,
    item_code text,
    item_parentid bigint
);

INSERT INTO item VALUES (1, 'Item 1', 'Item 1', NULL);
INSERT INTO item VALUES (2, 'Item 1.1', 'Item 1.1', 1);
INSERT INTO item VALUES (3, 'Item 1.1.1', 'Item 1.1.1', 2);
INSERT INTO item VALUES (4, 'Item 1.1.1.1', 'Item 1.1.1.1', 3);
INSERT INTO item VALUES (5, 'Item 1.1.1.1.1', 'Item 1.1.1.1.1', 4);

到目前为止,我必须使用' WITH RECURSIVE'来编写查询。检索细节。但是我不知道如何在函数内写入相同内容并返回项目名称。

WITH RECURSIVE itemtree (item_id, item_name, item_code,item_parentid,depth) AS (
            SELECT item_id,item_name, item_code,item_parentid,1 FROM item WHERE item_id = 5
            UNION
            SELECT child.item_id,child.item_name, child.item_code,child.item_parentid,depth+1 FROM item child
            INNER JOIN itemtree parent ON child.item_id = parent.item_parentid 
            )

SELECT array_to_string(array_agg(T.item_name), '>>>')  FROM (SELECT * FROM itemtree ORDER BY depth DESC) T;

我正在使用PostgreSQL 8.4.22

2 个答案:

答案 0 :(得分:1)

解决方案相当简单。首先想到我的想法是执行查询并使用SELECT INTOEXECUTE语句返回结果。 但这完全没必要。感谢另一篇SO帖子,How to write WITH(CTE) within function in PostgreSQL。 现在我已经更正了查询并将其发布在

下面
--Have to add a new procedure to find the parent
CREATE OR REPLACE FUNCTION getitemname(itemid bigint) RETURNS text
    LANGUAGE plpgsql STRICT
    AS $$
DECLARE
    item RECORD;
BEGIN  

    WITH RECURSIVE itemtree (item_id, item_name, item_code,item_parentid,depth) AS (
            SELECT item_id,item_name, item_code,item_parentid,1 FROM om_item WHERE item_id = $1 AND deleted = 0
            UNION
            SELECT child.item_id,child.item_name, child.item_code,child.item_parentid,depth+1 FROM om_item child
            INNER JOIN itemtree parent ON child.item_id = parent.item_parentid 
            )

    SELECT array_to_string(array_agg(T.item_name), '>>>') INTO item FROM (SELECT * FROM itemtree ORDER BY depth DESC) T;
    return item;

END;
$$;


SELECT getitemname(5);

答案 1 :(得分:0)

您可以将查询编写为INSERT INTO格式:

INSERT INTO item_names
SELECT name
FROM
(
    WITH RECURSIVE itemtree (item_id, item_name, item_code,item_parentid,depth) AS (
        SELECT item_id,item_name, item_code,item_parentid,1 FROM item WHERE item_id = 5
        UNION
        SELECT child.item_id,child.item_name, child.item_code,child.item_parentid,depth+1 FROM item child
        INNER JOIN itemtree parent ON child.item_id = parent.item_parentid 
    )
    SELECT array_to_string(array_agg(T.item_name), ' >>> ') AS name FROM (SELECT * FROM itemtree ORDER BY depth DESC) T
) res