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;