No hay nada malo con una función plpgsql para algo un poco más complejo. La única situación en la que el rendimiento puede verse afectado es cuando se anida una función plpgsql, porque el planificador de consultas no puede optimizar más el código contenido en el contexto de la consulta externa, lo que puede o no hacerlo más lento.
Más detalles más adelante respuesta:
- Diferencia entre lenguaje sql y lenguaje plpgsql en funciones de PostgreSQL
En el caso que nos ocupa es mucho más simple que muchos CASE
cláusulas en una consulta:
CREATE OR REPLACE FUNCTION get_stuff(_param text, _orderby text, _limit int)
RETURNS SETOF stuff AS
$func$
BEGIN
RETURN QUERY EXECUTE '
SELECT *
FROM stuff
WHERE col = $1
ORDER BY ' || quote_ident(_orderby) || ' ASC
LIMIT $2'
USING _param, _limit;
END
$func$ LANGUAGE plpgsql;
Llamar:
SELECT * FROM get_stuff('hello', 'col2', 100);
Notas
Utilice RETURN QUERY EXECUTE
para devolver los resultados de la consulta de una sola vez.
Usa quote_ident()
para que los identificadores se protejan contra SQLi.
O format()
para algo más complejo. Ver:
- Nombre de tabla como parámetro de función de PostgreSQL
Pasa valores de parámetros con USING
cláusula para evitar la conversión, cotización y SQLi una vez más.
Tenga cuidado de no crear conflictos de nombres entre los parámetros y los nombres de las columnas. Prefijé los nombres de los parámetros con un guión bajo (_
) en el ejemplo. Solo mi preferencia personal.
Su segunda función después de la edición no puede funcionar, porque solo devuelve parent
mientras que el tipo de retorno se declara SETOF stuff
. Puede declarar cualquiera tipo de devolución que desee, pero los valores de devolución reales deben coincidir con la declaración. Es posible que desee utilizar RETURNS TABLE
por eso.