首页 > 解决方案 > PostgreSQL RETURN NEXT 错误“返回多于一行”

问题描述

我有一个冗长的 PGPLSQL 函数:这是一个总结

CREATE FUNCTION get_features_by_buffer(
                    p_buffer GEOMETRY
                )
RETURNS SETOF JSON AS $BODY$
    DECLARE
        v_buffer GEOMETRY;
        v_sql TEXT
    BEGIN
    FOR REC IN EXECUTE $$(
                (
                    SELECT row_to_json(foo_pole) AS json FROM 
                       (
                         SELECT * FROM pole WHERE $$ || v_sql_where || $$
                       ) AS foo_pole
                 )
                 UNION ALL 
                 (
                    SELECT row_to_json(foo_transformerbank) AS json FROM 
                       (
                         SELECT * FROM transformerbank WHERE $$ || v_sql_where || $$) AS foo_transformerbank
                       )
                 )$$ LOOP
        RETURN NEXT REC.json;
    END LOOP;
    END
$BODY$
LANGUAGE plpgsql;

我的函数返回RETURNS SETOF JSON并且它比这里显示的要复杂一些,但是我已经运行了UNION ALL语句内部的查询并且没有语法或其他错误。这里看起来很奇怪,因为我一直在修补,但我最初是通过将查询语句放入v_sql并做来尝试的RETURN QUERY EXECUTE v_sql,这也给出了与此处显示的版本相同的错误。错误如下:

错误:查询“SELECT get_features_by_buffer(v_buffer)”返回多于一行内容
:PL/pgSQL 函数 get_features_by_pole_distance(字符变化,双精度)在 RETURN NEXT 的第 7 行

我一直在修补这个,不知道我在这里缺少什么,与UNION ALL?

标签: databasepostgresqlstored-procedurespostgresql-9.3

解决方案


据我所知,您不需要光标。只需使用生成的 SQL 作为输入return query execute ...

使用该format()函数生成动态 SQL 也更容易:

CREATE FUNCTION get_features_by_buffer(p_buffer GEOMETRY)
   RETURNS SETOF JSON 
AS 
$BODY$
DECLARE
    v_buffer GEOMETRY;
    v_sql TEXT
BEGIN
  RETURN QUERY EXECUTE 
    format(
      'SELECT row_to_json(foo_pole) AS json 
      FROM (
        SELECT * 
        FROM pole 
        WHERE %s
      ) AS foo_pole
      UNION ALL 
      SELECT row_to_json(foo_transformerbank) AS json 
      FROM (
        SELECT * 
        FROM transformerbank 
        WHERE %s
      ) AS foo_transformerbank', v_sql_where, v_sql_where);
 END
$BODY$
LANGUAGE plpgsql;

由于该函数被声明为returns setof您必须像表一样使用它:

select * 
from get_features_by_buffer(...);

推荐阅读