sql - 从函数返回时复合数据类型缺少值

标签 sql postgresql plpgsql postgresql-9.2 composite-types

我有一个返回 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;

最佳答案

确保你像这样调用函数:

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;

关于sql - 从函数返回时复合数据类型缺少值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22179614/

相关文章:

python - Django 测试——无法删除并重新创建测试数据库

ruby-on-rails - "DEPRECATION WARNING: Modifying already cached Relation"Postgres MAX/GREATEST 组合查询

sql - 多对多的复杂 SQL 查询

android - 在数据库中存储查询语句

SQL替换函数

sql - 参数化表名

postgresql - 将 SETOF 转换为字符串

sql - 测试动态查询中是否有任何更新

sql - 是否可以在 SQL 中使用 'Where' 子句仅显示仅包含字母和数字的字段?

MySQL 截断了我的第一个零数据