Les fonctions PL / PgSQL et plain SQL font toutes deux partie d'un ensemble d'outils plus large et doivent être considérées dans ce contexte. J'ai tendance à y penser en termes d'échelle de puissance ascendante assortie d'une complexité et d'un coût croissants, où vous devriez utiliser l'outil le plus simple qui fera bien le travail:
- Utilisez des vues lorsque cela est possible
- Lorsqu'une vue ne convient pas, utilisez une fonction SQL
- Lorsqu'une fonction SQL ne convient pas, utilisez PL / PgSQL.
- Lorsque PL / PgSQL est trop limité ou pas assez expressif, utilisez PL / Perl, PL / Python, PL / V8, PL / Java, ou quelle que soit votre préférence.
- ... et où aucun PL ne fera le travail, utilisez un programme externe et éventuellement
LISTENet NOTIFYpour lui parler.
Très souvent, une vue est suffisante lorsque vous pensez qu'une fonction est nécessaire. Même si cela coûte extrêmement cher à SELECTla vue entière, les WHEREclauses de la requête faisant référence à la vue sont généralement poussées vers le bas dans la vue et peuvent entraîner des plans de requête très différents. J'ai souvent eu de grandes améliorations des performances de la conversion des fonctions SQL en vues.
La principale fois où vous constatez que vous ne pouvez pas utiliser une vue et que vous devez envisager une fonction SQL est lorsque:
- Des paramètres qui ne peuvent pas être exprimés comme de simples
WHEREclauses sont nécessaires, comme un paramètre dans une WITHexpression
- Vous voulez une barrière de sécurité via une
SECURITY DEFINERfonction, et les security_barriervues dans PostgreSQL 9.2 et supérieur ne sont pas suffisantes pour vos besoins;
- Vous avez besoin de paramètres qui ne sont pas poussés vers le bas dans les sous-clauses d'une vue par l'optimiseur et que vous souhaitez contrôler plus directement; ou
- Il y a beaucoup de paramètres ou il y a beaucoup de répétitions des paramètres, il est donc impossible d'écrire la requête sous forme de vue.
Pour la plupart de ces tâches, une simple fonction SQL fonctionne correctement et est souvent plus facile à lire que PL / PgSQL. Les fonctions SQL déclarées STABLEou IMMUTABLE(et non également déclarées STRICTou SECURITY DEFINER) peuvent également être insérées dans l'instruction appelante. Cela supprime la surcharge des appels de fonction et peut parfois entraîner d'énormes avantages en termes de performances lorsqu'une condition WHERE dans la fonction appelante est poussée dans la fonction SQL par l'optimiseur. Utilisez les fonctions SQL chaque fois qu'elles sont suffisantes pour la tâche.
La principale fois où les fonctions SQL ne feront pas le travail, c'est quand vous avez besoin de beaucoup de logique. Si / alors / sinon les opérations que vous ne pouvez pas exprimer sous forme d' CASEinstructions, beaucoup de réutilisation des résultats calculés, la création de valeurs à partir de morceaux, la gestion des erreurs, etc. PL / PgSQL est alors très pratique. Choisissez PL / PgSQL lorsque vous ne pouvez pas utiliser les fonctions SQL ou qu'elles ne conviennent pas, comme pour:
- SQL dynamique et DDL dynamique via l'
EXECUTEinstruction
- Lorsque vous souhaitez des
RAISEerreurs / avertissements pour les journaux ou le client
- Lorsque vous avez besoin de la gestion des exceptions - vous pouvez intercepter et gérer les erreurs avec des
EXCEPTIONblocs au lieu de terminer la transaction en cas d'erreur
- Logique conditionnelle complexe qui ne correspond pas
CASE ... WHENtrès bien
- Beaucoup de réutilisation de valeurs calculées que vous ne pouvez pas adapter
WITHet CTE
- Création d'enregistrements dynamiques
- Vous devez effectuer une action après avoir produit le jeu de résultats
Avec les expressions de table communes (CTE), en particulier les CTE inscriptibles et WITH RECURSIVEje trouve que j'utilise PL / PgSQL beaucoup moins qu'auparavant parce que SQL est beaucoup plus expressif et puissant. J'utilise beaucoup plus les vues et les fonctions SQL simples. Il convient de se rappeler que les fonctions SQL simples peuvent contenir plusieurs instructions; la dernière instruction est le résultat de la fonction.