PostgreSQL RETURN NEXT错误“返回多行”

问题描述 投票:0回答:1

我有一个很长的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(字符变化,双精度)第7行在RETURN NEXT

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

database postgresql stored-procedures postgresql-9.3
1个回答
0
投票

据我所知,你不需要光标。只需使用生成的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(...);
© www.soinside.com 2019 - 2024. All rights reserved.