从函数返回时复合数据类型缺失值

时间:2014-03-04 18:07:20

标签: sql postgresql plpgsql postgresql-9.2 compositetype

我有一个函数返回setof复合数据类型。当我运行该函数时,复合数据类型中定义的两列中只有一列中包含数据。在对问题进行故障排除时,我对复合数据类型执行了RAISE NOTICE,并且该列中的数据缺少结果集中的数据。我在RETURN NEXT之前和之后测试过。我正在使用PostgreSQL 9.2 知道为什么结果集缺少数据吗?

CREATE TYPE map_data AS (lid uuid, tile_ids uuid [] );

CREATE OR REPLACE FUNCTION get_map_data(mid_val uuid) RETURNS SETOF map_data AS $$
DECLARE
    j uuid;
    b uuid;
    m map_data%rowtype;
    tid uuid []; --tile ids
BEGIN
FOR j IN
    SELECT lid FROM map_layers WHERE "mid" = mid_val
LOOP
    FOREACH b IN ARRAY (SELECT tiles FROM layer_tiles WHERE lid = j) 
    LOOP
        tid := array_append(tid,b);
    END LOOP;
    SELECT j, tid INTO m;
    RETURN NEXT m;
    tid := '{}'; --clear the array.
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql;

1 个答案:

答案 0 :(得分:0)

请务必按以下方式调用此函数:

SELECT * FROM get_map_data( ... );

而不是这样:

SELECT get_map_data( ... );

或者您将整个复合类型作为单个列。

可能的解释

UUIDs can be written with enclosing curly braces ({}) in text representation.这恰好与文字数组常量的语法相匹配,后者使用相同的大括号。此文字可以转换为uuiduuid[]类似:

'{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}'

这可能会引入歧义。只是推测,但我可以想象一些客户端对语法规则感到困惑,并将元素和数组连接到一个数据。

即使这个SQL Fiddle也会遇到JDBC错误! (虽然同样适用于整数数据。)

更好的选择

无论哪种方式,你的功能都有很多毫无意义的努力。循环,取消和重建数组,...
整个shebang可以用这个简单快速的查询替换:

SELECT m.lid, tiles
FROM   map_layers  m
JOIN   layer_tiles l USING (lid)
WHERE  m.mid = $mid_val;

如果需要,将其包装到SQL函数中:

CREATE OR REPLACE FUNCTION get_map_data(_mid_val uuid)
  RETURNS SETOF map_data AS
$func$
SELECT m.lid, l.tiles
FROM   map_layers  m
JOIN   layer_tiles l USING (lid)
WHERE  m.mid = $1
$func$ LANGUAGE sql;