IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

37.4. Déclarations

Toutes les variables utilisées dans un bloc doivent être déclarées dans la section déclaration du bloc. La seule exception est que la variable de boucle d'une boucle FOR effectuant une itération sur des valeurs entières est automatiquement déclarée comme variable entière.

Les variables PL/pgSQL peuvent être de n'importe quel type de données tels que integer, varchar et char.

Quelques exemples de déclarations de variables :

id_utilisateur integer;
quantité numeric(5);
url varchar;
ma_ligne nom_table%ROWTYPE;
mon_champ nom_table.nom_colonne%TYPE;
une_ligne RECORD;

La syntaxe générale d'une déclaration de variable est :

nom [ CONSTANT ] type [ NOT NULL ] [ { DEFAULT | := } expression ];

La clause DEFAULT, si indiquée, spécifie la valeur initiale assignée à la variable quand on entre dans le bloc. Si la clause DEFAULT n'est pas indiquée, la variable est initialisée à la valeur SQL NULL. L'option CONSTANT empêche l'assignation de la variable, de sorte que sa valeur reste constante pour la durée du bloc. Si NOT NULL est spécifié, l'assignement d'une valeur NULL aboutira à une erreur d'exécution. Les valeurs par défaut de toutes les variables déclarées NOT NULL doivent être spécifiées non NULL.

La valeur par défaut est évaluée à chaque entrée du bloc. Ainsi, par exemple, l'assignation de now() à une variable de type timestamp donnera à la variable l'heure de l'appel de la fonction courante, et non l'heure au moment où la fonction a été précompilée.

Exemples :

quantité integer DEFAULT 32;
url varchar := 'http://mysite.com';
id_utilisateur CONSTANT integer := 10;

Les paramètres passés aux fonctions sont nommés par les identifiants $1, $2, etc. Éventuellement, des alias peuvent être déclarés pour les noms de paramètres de type $ n afin d'améliorer la lisibilité. L'alias ou l'identifiant numérique peuvent être utilisés indifféremment pour se référer à la valeur du paramètre.

Il existe deux façons de créer un alias. La façon préférée est de donner un nom au paramètre dans la commande CREATE FUNCTION , par exemple :

CREATE FUNCTION taxe_ventes(sous_total real) RETURNS real AS $$
BEGIN
    RETURN sous_total * 0.06;
END;

L'autre façon, la seule disponible pour les versions antérieures de PostgreSQL™ 8.0, est de déclarer explicitement un alias en utilisant la syntaxe de déclaration

nom ALIAS FOR $n;

Le même exemple dans ce style ressemble à

CREATE FUNCTION taxe_ventes(real) RETURNS real AS $$
DECLARE
    sous_total ALIAS FOR $1;
BEGIN
    RETURN sous_total * 0.06;
END;
$$ LANGUAGE plpgsql;

Quelques exemples de plus :

CREATE FUNCTION instr(varchar, integer) RETURNS integer AS $$
DECLARE
    v_string ALIAS FOR $1;
    index ALIAS FOR $2;
BEGIN
    -- quelques traitements utilisant ici v_string et index
END;
$$ LANGUAGE plpgsql;


CREATE FUNCTION concat_champs_selectionnes(in_t un_nom_de_table) RETURNS text AS $$
BEGIN
    RETURN in_t.f1 || in_t.f3 || in_t.f5 || in_t.f7;
END;
$$ LANGUAGE plpgsql;

Quand une fonction PL/pgSQL est déclarée avec des paramètres en sortie, ces derniers se voient attribués les noms $ n et des alias optionnels de la même façon que les paramètres en entrée. Un paramètre en sortie est réellement une variable qui commence avec la valeur NULL ; il devrait se voir attribuer une valeur lors de l'exécution de la fonction. La valeur finale du paramètre est ce qui est renvoyée. Par exemple, l'exemple sales-tax aurait pu être écrit de cette façon :

CREATE FUNCTION taxe_ventes(sous_total real, OUT taxe real) AS $$
BEGIN
    taxe := sous_total * 0.06;
END;
$$ LANGUAGE plpgsql;

Notez que nous avons omis RETURNS real -- nous aurions pu l'inclure mais cela aurait été redondant.

Les paramètres en sortie sont encore plus utiles lors du retour de plusieurs valeurs. Un exemple trivial est :

CREATE FUNCTION somme_n_produits(x int, y int, OUT somme int, OUT produit int) AS $$
BEGIN
    somme := x + y;
    produit := x * y;
END;
$$ LANGUAGE plpgsql;

D'après ce qui a été vu dans la Section 33.4.3, « Fonctions avec des paramètres en sortie », ceci crée réellement un type d'enregistrement anonyme pour les résultats de la fonction. Si une clause RETURNS est donnée, elle doit spécifier RETURNS record.

Lorsque le type de retour d'une fonction PL/pgSQL est déclaré comme type polymorphe (anyelement ou anyarray), un paramètre spécial $0 est créé. Son type de donnée est le type effectif de retour de la fonction, déduit d'après les types d'entrée (voir la Section 33.2.5, « Types et fonctions polymorphes »). Ceci permet à la fonction d'accéder à son type de retour réel comme on le voit ici avec la Section 37.4.2, « Copie de types ». $0 est initialisé à NULL et peut être modifié par la fonction, de sorte qu'il peut être utilisé pour contenir la variable de retour si besoin est, bien que cela ne soit pas requis. On peut aussi donner un alias à $0. Par exemple, cette fonction s'exécute comme un opérateur + pour n'importe quel type de données.

CREATE FUNCTION ajoute_trois_valeurs(v1 anyelement, v2 anyelement, v3 anyelement)
RETURNS anyelement AS $$
DECLARE
    resultat ALIAS FOR $0;
BEGIN
    resultat := v1 + v2 + v3;
    RETURN resultat;
END;
$$ LANGUAGE plpgsql;

Le même effet peut être obtenu en déclarant un ou plusieurs paramètres en sortie comme anyelement ou anyarray. Dans ce cas, le paramètre spécial $0 n'est pas utilisé ; les paramètres en sortie servent ce même but. Par exemple :

CREATE FUNCTION ajoute_trois_valeurs(v1 anyelement, v2 anyelement, v3 anyelement,
                                 OUT somme anyelement)
AS $$
BEGIN
    somme := v1 + v2 + v3;
END;
$$ LANGUAGE plpgsql;
nom nom_table%ROWTYPE;
nom nom_type_composite;

Une variable de type composite est appelée variable ligne (ou variable row-type). Une telle variable peut contenir une ligne entière de résultat de requête SELECT ou FOR , du moment que l'ensemble de colonnes de la requête correspond au type déclaré de la variable. Les champs individuels de la valeur row sont accessibles en utilisant la notation pointée, par exemple varligne.champ.

Une variable ligne peut être déclarée de façon à avoir le même type que les lignes d'une table ou vue existante, en utilisant la notation nom_table %ROWTYPE ou elle peut être déclarée en donnant un nom de type composite (chaque table ayant un type de données associé du même nom, il importe peu dans PostgreSQL™ que vous écriviez %ROWTYPE ou pas. Cependant la forme utilisant %ROWTYPE est plus portable).

Les paramètres d'une fonction peuvent être des types composites (lignes complètes de tables). En ce cas, l'identifiant correspondant $ n sera une variable ligne à partir de laquelle les champs peuvent être sélectionnés, par exemple $1.id_utilisateur.

Seules les colonnes définies par l'utilisateur d'une ligne de table sont accessibles dans une variable de type ligne, et non l'OID ou d'autres colonnes systèmes (parce que la ligne pourrait être issue d'une vue). Les champs du type ligne héritent des tailles des champs de la table ou de leur précision pour les types de données tels que char( n ).

Voici un exemple d'utilisation des types composites. table1 et table2 sont des tables ayant au moins les champs mentionnés :

CREATE FUNCTION assemble_champs(t_ligne table1) RETURNS text AS $$
DECLARE
    t2_ligne table2%ROWTYPE;
BEGIN
    SELECT * INTO t2_ligne FROM table2 WHERE ... ;
    RETURN t_ligne.f1 || t2_ligne.f3 || t_ligne.f5 || t2_ligne.f7;
END;
$$ LANGUAGE plpgsql;

SELECT assemble_champs(t.*) FROM table1 t WHERE ... ;