Only addressing your second question about EXECUTE
and USING
:
The elephant in the room: the suggested alternative is utter nonsense for multiple reasons.
The USING
clause of EXECUTE
is used to pass values. Not literals, not identifiers, not other syntax elements, only values. The same values you can pass to prepared statements because, internally, that's exactly what happens. The statement is prepared an then executed using values provided by USING
.
This is many-fold nonsense:
return query EXECUTE 'SELECT idFROM items ORDER BY $1' USING order_by_p;
ORDER BY
does not make sense with a constant value, would be just noise.order_by_p
is supposed to be a column name, which is supposed to be interpreted as identifier, not as data value. You never useUSING
for that. See above.- If you concatenate identifiers into SQL strings, you must escape them to avoid SQL injection and other sneaky errors. With
format()
using the%I
specifier or withquote_ident()
.
Would work like this:
CREATE OR REPLACE FUNCTION get_items_orderby(order_by_p text) RETURNS TABLE(id int) AS$func$BEGIN RETURN QUERY EXECUTE format(' SELECT id FROM items ORDER BY %I', order_by_p);END$func$ LANGUAGE plpgsql;
As long as you don't nest this function in outer queries (other than SELECT * FROM my_func()
), and you don't need to optimize performance (like for many repeated calls in the same session), there is nothing wrong it.
Note that identifiers are case sensitive and you have to provide correct spelling. Related answers: