我的职责是提取XML节点。代码如下:
var CarouselView = Ember.View.extend({
templateName: 'views/carousel',
elementId: 'carousel',
contentBinding: 'content',
...
正如您所看到的,该函数是递归的,目标是从我们没有信息的多个XML节点收集字段值,我们在标记下有多少个节点。 (我有一个带返回表的版本,但该方法太慢。)我使用自己定义的自定义类型,当我使用CREATE TYPE xml_node_looper_record AS (
allomany xml,
i integer,
actual_node text,
nodi_parts text[]
);
CREATE OR REPLACE FUNCTION ds.xml_node_looper_rec(rec xml_node_looper_record)
RETURNS SETOF xml_node_looper_record AS
$BODY$
DECLARE
nodes text[];
field_val text;
r xml_node_looper_record;
n integer;
BEGIN
nodes = xpath(rec.actual_node, rec.allomany);
IF nodes[1] IS NOT NULL THEN
rec.i = rec.i + 1;
FOR n IN 1..array_upper(nodes, 1) LOOP
IF rec.i = array_upper(rec.nodi_parts, 1) THEN
field_val = trim(ARRAY[xpath(rec.actual_node || '/text()', rec.allomany)]::text, ' {}"');
IF field_val IS NOT NULL AND field_val != '' THEN
RAISE NOTICE '% % % %', n, rec.actual_node, rec.i, field_val;
RETURN NEXT (NULL::xml, rec.i, rec.actual_node, ARRAY[field_val]::text[]);
END IF;
END IF;
SELECT ds.xml_node_looper_rec((rec.allomany, rec.i, rec.actual_node || '[' || n::text || ']' || rec.nodi_parts[rec.i + 1], rec.nodi_parts)) INTO r;
END LOOP;
END IF;
END;
$BODY$
LANGUAGE plpgsql VOLATILE COST 100;
检查返回值时,我可以在“消息”选项卡上看到pgAdmin中的结果,但RAISE NOTICE
命令不返回任何内容,只返回一个空表。
我的类型的参数:
有什么问题?
答案 0 :(得分:2)
您不会传播嵌套调用的结果。 RETURN NEXT
将结果推送到与函数调用相关的堆栈。但是这个堆栈是私有的 - 如果调用者没有获取此堆栈,则清除结果。无论如何 - 任何函数实例(被调用函数)都有自己的结果堆栈。此堆栈未共享。
PL / pgSQL中的递归表函数应如下所示:
postgres=# CREATE OR REPLACE FUNCTION foo(level int) RETURNS SETOF int AS $$
BEGIN
IF level > 5 THEN RETURN; END IF;
RETURN NEXT level;
--!! must to take result of nested call
RETURN QUERY SELECT * FROM foo(level + 1);
RETURN;
END;
$$ LANGUAGE plpgsql;
postgres=# SELECT * FROM foo(1);
┌─────┐
│ foo │
╞═════╡
│ 1 │
│ 2 │
│ 3 │
│ 4 │
│ 5 │
└─────┘
(5 rows)
您的代码相当于代码:
postgres=# CREATE OR REPLACE FUNCTION foo(level int) RETURNS SETOF int AS $$
BEGIN
IF level > 5 THEN RETURN; END IF;
RETURN NEXT level;
-- error, only call of nested function, but returned table is lost
PERFORM foo(level + 1);
RETURN;
END;
$$ LANGUAGE plpgsql;
postgres=# SELECT * FROM foo(1);
┌─────┐
│ foo │
╞═════╡
│ 1 │
└─────┘
(1 row)