1

I'm trying to convert a dynamic query result into json and then return that json as the result of this function (this is a simplified version, the WHERE clause in my actual code is considerably longer).

CREATE OR REPLACE FUNCTION get_data_as_json(tbl regclass, p_version_id integer)
  RETURNS json AS $$
BEGIN
    RETURN to_json( EXECUTE 'SELECT * FROM '|| tbl
                         || ' WHERE version_id = p_budget_version_id' );
END;
$$ LANGUAGE plpgsql;

However, this code results in a type "execute" does not exist error.
How do I run the dynamic query, and then convert the result to JSON?

Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
RodeoClown
  • 13,338
  • 13
  • 52
  • 56
  • check http://hashrocket.com/blog/posts/faster-json-generation-with-postgresql - isn't "select array_to_json(array_agg(row_to_json(t)))" example what you´re looking for? – Leo Feb 06 '14 at 01:23
  • That doesn't take the dynamic portion of the question into account (but the "array_to_json(array_agg(row_to_json" might help. Thanks!) – RodeoClown Feb 06 '14 at 01:28
  • for the dynamic part, don't you have to use return query? see http://stackoverflow.com/questions/7945932/how-return-result-of-a-select-inside-a-function-in-postgresql – Leo Feb 06 '14 at 01:34
  • not in this instance, because I'm not returning a SETOF – RodeoClown Feb 06 '14 at 01:53
  • I see... you're returning a big string... :-( – Leo Feb 06 '14 at 02:08

2 Answers2

3

If you were returning SETOF you'd need to use the RETURN QUERY EXECUTE construct, producing a dynamic query that returns what you want. Since you're not, use regular EXECUTE ... INTO a variable that you then return.

Untested, but in vaguely the right direction:

CREATE OR REPLACE FUNCTION get_data_as_json(tbl regclass, p_version_id integer) RETURNS json AS $$
DECLARE
    my_result json;
BEGIN
    EXECUTE format('SELECT to_json(*) FROM %I WHERE version_id = p_budget_version_id',tbl) INTO my_result;
    RETURN my_result;
END;
$$ LANGUAGE plpgsql;
Craig Ringer
  • 307,061
  • 76
  • 688
  • 778
3

What @Craig wrote. But a somewhat different solution with additional fixes:

CREATE OR REPLACE FUNCTION get_data_as_json(tbl regclass
                                          , p_version_id integer
                                          , OUT my_result json) AS
$func$
BEGIN
   EXECUTE format('SELECT to_json(*) FROM %s
                   WHERE  version_id = $1'
                  ,tbl)
   INTO  my_result
   USING p_version_id;
END
$func$ LANGUAGE plpgsql;
Community
  • 1
  • 1
Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228