PL/pgSQL est un langage structuré en blocs. Le texte complet de la définition d'une fonction doit être un bloc. Un bloc est défini comme :
[ <<label>> ] [ DECLARE déclarations ] BEGIN instructions END [ label ];
Chaque déclaration et chaque expression au sein du bloc est terminé par un point-virgule. Un bloc qui apparaît à l'intérieur d'un autre bloc doit avoir un point-virgule après END (voir l'exemple ci-dessus) ; néanmoins, le END final qui conclut le corps d'une fonction n'a pas besoin de point-virgule.
Une erreur habituelle est d'écrire un point-virgule immédiatement après BEGIN. C'est incorrect et a comme résultat une erreur de syntaxe.
Un label est seulement nécessaire si vous voulez identifier le bloc à utiliser dans une instruction EXIT ou pour qualifier les noms de variable déclarées dans le bloc. Si un label est écrit après END, il doit correspondre au label donné au début du bloc.
Tous les mots clés sont insensibles à la casse. Les identifiants sont convertis implicitement en minuscule sauf dans le cas de l'utilisation de guillemets doubles. Le comportement est donc identique à celui des commandes SQL habituelles.
Les commentaires fonctionnent de la même manière tant dans du PL/pgSQL que dans le code SQL. Un double tiret (--) commence un commentaire et celui-ci continue jusqu'à la fin de la ligne. Un /* commence un bloc de commentaire qui continue jusqu'au */ correspondant. Les blocs de commentaires peuvent imbriquer les uns dans les autres.
Chaque expression de la section expression d'un bloc peut être un sous-bloc. Les sous-blocs peuvent être utilisés pour des groupements logiques ou pour situer des variables locales dans un petit groupe d'instructions. Les variables déclarées dans un sous-bloc masquent toute variable nommée de façon similaire dans les blocs externes pendant toute la durée du sous-bloc. Cependant, vous pouvez accéder aux variables externes si vous qualifiez leur nom du label de leur bloc. Par exemple :
CREATE FUNCTION une_fonction() RETURNS integer AS $$ << blocexterne >> DECLARE quantite integer := 30; BEGIN RAISE NOTICE 'quantité vaut ici %', quantite; -- affiche 30 quantite := 50; -- -- Crée un sous-bloc -- DECLARE quantite integer := 80; BEGIN RAISE NOTICE 'quantite vaut ici %', quantite; -- affiche 80 RAISE NOTICE 'la quantité externe vaut ici %', blocexterne.quantite; -- affiche 50 END; RAISE NOTICE 'quantité vaut ici %', quantite; -- affiche 50 RETURN quantite; END; $$ LANGUAGE plpgsql;
Il existe un bloc externe caché entourant le corps de toute fonction PL/pgSQL. Ce bloc fournit la déclaration des paramètres de la fonction ainsi que quelques variables spéciales comme FOUND (voir la Section 39.5.5, « Obtention du statut du résultat »). Le bloc externe a pour label le nom de la fonction. Cela a pour conséquence que les paramètres et les variables spéciales peuvent être qualifiés du nom de la fonction.
Il est important de ne pas confondre l'utilisation de BEGIN/END pour grouper les instructions dans PL/pgSQL avec les commandes pour le contrôle des transactions. Les BEGIN/END de PL/pgSQL ne servent qu'au groupement ; ils ne débutent ni ne terminent une transaction. Les fonctions standards et les fonctions triggers sont toujours exécutées à l'intérieur d'une transaction établie par une requête extérieure -- ils ne peuvent pas être utilisés pour commencer ou valider une transaction car ils n'auraient pas de contexte pour s'exécuter. Néanmoins, un bloc contenant une clause EXCEPTION forme réellement une sous-transaction qui peut être annulée sans affecter la transaction externe. Pour plus d'informations sur ce point, voir la Section 39.6.5, « Récupérer les erreurs ».