PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

PostgreSQL paramétré Order By / Limit dans la fonction de table

Il n'y a rien de mal avec une fonction plpgsql pour tout ce qui est un peu plus complexe. La seule situation où les performances peuvent en pâtir est lorsqu'une fonction plpgsql est imbriquée, car le planificateur de requêtes ne peut pas optimiser davantage le code contenu dans le contexte de la requête externe, ce qui peut ou non la ralentir.
Plus de détails plus tard réponse :

  • Différence entre le langage sql et le langage plpgsql dans les fonctions PostgreSQL

Dans le cas présent, c'est beaucoup plus simple que beaucoup de CASE clauses dans une requête :

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;

Appel :

SELECT * FROM get_stuff('hello', 'col2', 100);

Remarques

Utilisez RETURN QUERY EXECUTE pour renvoyer les résultats de la requête en une seule fois.

Utilisez quote_ident() pour les identifiants à protéger contre SQLi.
Ou format() pour tout ce qui est plus complexe. Voir :

  • Nom de table en tant que paramètre de fonction PostgreSQL

Passez les valeurs des paramètres avec le USING clause pour éviter à nouveau de caster, de citer et SQLi.

Veillez à ne pas créer de conflits de nommage entre les paramètres et les noms de colonne. J'ai préfixé les noms de paramètres avec un trait de soulignement (_ ) dans l'exemple. Juste ma préférence personnelle.

Votre deuxième fonction après la modification ne peut pas fonctionner, car vous ne renvoyez que parent tandis que le type de retour est déclaré SETOF stuff . Vous pouvez déclarer tout type de retour que vous aimez, mais les valeurs de retour réelles doivent correspondre à la déclaration. Vous voudrez peut-être utiliser RETURNS TABLE pour ça.