You can't avoid execute here, per igor's comment. The best alternative is to create a function that creates a function, which you can then call as needed. Example:
create function gen_select_server(p_id text)
returns boolean
as $gen$
begin
execute $exec$
create function $exec$ || quote_ident('select_server_' || p_id) || $exec$
returns integer
as $body$
begin
return serialnum
from $exec$ || quote_ident('tbl_' || p_id) || $exec$
where id = $exec$ || quote_literal('id_' || p_id) || $exec$;
end;
$body$ language plpgsql;
$exec$;
return true;
end;
$gen$ language plpgsql;
-- usage:
select gen_select_server('1234'); -- call this only once; uses execute
select * from select_server_1234(); -- no execute here
As the above highlights, it can get messy with string delimiters. Also note that the above isn't your original function -- it's primarily to illustrate how to quote things properly within the big $exec$ "string" block.
I'd recommend to stick to using execute, that being said. Or using an ORM, for that matter. Maintaining these micro-optimizations is potentially a pain worse than the superficial gain in performance.
EXECUTE. 2) Why you do not want to useEXECUTE?