Langages procéduraux PostgreSQL - différences entre PL / pgSQL et SQL

20

Quelqu'un peut-il résumer les différences entre:

http://www.postgresql.org/docs/9.1/static/xfunc-sql.html

et

http://www.postgresql.org/docs/9.1/static/plpgsql.html

?

Points principaux:

  • différences de conception
  • étant donné une famille problématique, commodité d'utilisation
  • problèmes politiques
Gismo Ranas
la source
1
Tout d'abord, les fonctions SQL (aka. Query language) n'impliquent aucun des langages procéduraux de PostgreSQL. Deuxièmement, vous avez déjà trouvé la meilleure source où l'on peut trouver les réponses à vos questions (à l'exception de la dernière - que voulez-vous dire exactement par «questions politiques»?)
dezso
J'ai demandé de résumer tous les principaux problèmes, pas nécessairement en utilisant la documentation que j'ai collée, mais aussi en utilisant des impressions personnelles. Ces liens sont là juste pour être sûr que tout le monde comprend de quoi il s'agit.
Gismo Ranas
Ne le prenez pas comme une agression, mais une fois que vous les avez lues, vous pouvez les résumer vous-même :) Sinon, votre question est un peu large, mais avec un peu de temps, je vais essayer de rassembler quelques réflexions.
dezso
1
Ne négligez pas les autres langages procéduraux. En particulier, PL / Perl est extrêmement utile pour les domaines où PL / PgSQL est trop limité; PL / Pythonu fait le travail si vous préférez Python mais n'offre pas de modèle de sécurité comme PL / Perl. Il existe également PL / V8 (JavaScript) en tant que module complémentaire.
Craig Ringer
1
Salut cataldo - Je voudrais juste vous souhaiter la bienvenue sur le site car c'est votre première question ici. Merci d'avoir posté et j'espère que vous resterez.
Jack Douglas

Réponses:

27

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.

Craig Ringer
la source
Très bien dit! (un +1 supplémentaire virtuel bien que virtuel pour mentionner les CTE inscriptibles)
dezso
Cette réponse explique également pourquoi certaines fonctions nécessitent une clôture d'optimisation .
Eonil
8

plpgsqlest un langage procédural à part entière, avec des variables, des constructions en boucle, etc. Une SQLfonction est simplement une sous-requête. Une fonction SQL, si elle est déclarée STABLEou IMMUTABLEnon STRICT, peut également être insérée dans la requête appelante, comme si elle était écrite sur chaque référence.

kgrittn
la source