PostgreSQL RETURN NEXT错误“返回了多行”

时间:2018-09-04 03:52:37

标签: database postgresql stored-procedures postgresql-9.3

我有一个很长的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有关系吗?

1 个答案:

答案 0 :(得分: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(...);