Les fonctions écrites en PL/pgSQL sont définies auprès du serveur en exécutant les commandes CREATE FUNCTION. Une telle commande pourrait ressembler à ceci :
CREATE FUNCTION une_fonction(integer, text) RETURNS integer
AS 'texte du corps de la fonction
'
LANGUAGE plpgsql;
Le corps de la fonction est une simple chaîne littérale pour ce qui
concerne CREATE FUNCTION
. Il est souvent utile
d'utiliser les guillemets dollars (voir Section 4.1.2.4) pour écrire le corps de la fonction,
plutôt que la syntaxe normale à base de guillemets simples. Sans les
guillemets dollar, tout guillemet simple et antislashs dans le corps de
la fonction doit être échappé en les doublant. Pratiquement tous les
exemples de ce chapitre utilisent les littéraux en guillemets dollars dans
les corps des fonctions.
PL/pgSQL est un langage structuré en blocs. Le texte complet du corps d'une fonction doit être un bloc. Un bloc est défini comme :
[ <<label
>> ] [ DECLAREdéclarations
] BEGINinstructions
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 41.5.5). 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. Voir Section 41.8
pour plus d'informations sur la gestion des transactions dans
PL/pgSQL. De plus, 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 41.6.8.