|
|
||||
Ouverture de sessionNavigationContactez-nousAdministration du site : RechercheSujets du forumSujets actifsNouveaux sujets:SyndicationSondageQuelle est la version de PostgreSQL la plus répandue sur vos serveurs ? 8.3 10% 8.2 42% 8.1 40% 8.0 2% 7.4 6% 7.3 ou antérieure 0% Nombre de votes: 48 |
Écrire et utiliser des fonctions retournant une valeur de type composite (ROWTYPE)Technique | Écrire et utiliser des fonctions retournant une valeur de type composite (ROWTYPE)Par RockyRoad le 27/08/2008 - 19:42 Bien que nouvelle utilisatrice de PG, j'ai choisi de présenter un mini-article sur l'utilisation des ROWTYPE dans PL/pgSQL, car je crois qu'il pourrait être utile à beaucoup. Je n'ai hélas pas beaucoup de temps à y consacrer, mais je compte sur votre participation pour m'aider à le clarifier. En effet je n'ai rien trouvé de tel sur le web et j'ai dû passer du temps, pour "trouver le pot aux roses", c'est-à -dire une syntaxe correcte utilisable pour mon application (GPL) que je vous dévoilerai plus tard. Merci à Guillaume Lelarge pour son aide. Au-delà de partager son expérience, il s'est joint activement à mes réflexions et suggéré les solutions qui m'ont mise sur la bonne voie. Lorsqu'on crée une table, PG crée automatiquement un type (structure) décrivant la composition d'une ligne, c'est-à -dire la liste des champs. Si on veut manipuler des lignes indépendamment d'une table, on peut déclarer un type, par exemple: test=> L'interpréteur psql nous répond: CREATE TYPE La fonction suivante construit une ligne du type 'names' : test=> CREATE FUNCTION test=> On reçoit le message, puis le résultat en une seule colonne
NOTICE: BuildName('Pierre', 'Dupond')
Si on veut distinguer les colonnes, conformément à la définition du type, il faut utiliser la syntaxe test=>
NOTICE: BuildName('Pierre', 'Dupond')
On obtient bien le rĂ©sultat en 3 colonnes. Mais on reçoit 3 FOIS le message (il y a 3 champs). Que se passe-t-il ? Le comportement est identique avec une table: test=> NOTICE: table "person" does not exist, skipping test=> CREATE FUNCTION test=> On reçoit le message, puis le rĂ©sultat en une seule colonne NOTICE: BuildPerson(1, 'Dupond') Si on veut insĂ©rer les rĂ©sultats dans la table, il faut adapter la syntaxe pour obtenir des champs distincts test=> NOTICE: BuildPerson(2, 'Dupond') test=> NOTICE: BuildPerson(2, 'Dupond') On reçoit aussi 3 FOIS le message , mais la rangĂ©e n'est insĂ©rĂ©e qu'une fois test=> id | name | data Tout va bien ? On avance ... mais: Si la fonction comporte elle-mĂŞme une instruction INSERT, on peut avoir un problème: test=> CREATE FUNCTION test=> NOTICE: AddPerson(3, 'Durand') Eh oui ! Comme les messages rĂ©pĂ©tĂ©s pouvaient nous le laisser prĂ©voir, la fonction est appelĂ©e plusieurs fois, avec les mĂŞmes arguments, ce que notre clĂ© primaire interdit. Remarquez que, la transaction ayant Ă©chouĂ©, aucune ligne n'est finalement ajoutĂ©e. test=> id | name | data Pas de souci cependant si on Ă©vite la syntaxe ().* lors de l'invocation: test=> DELETE 0 Attention si on rĂ©cupère le rĂ©sultat dans une variable (par exemple dans une fonction rĂ©cursive) test=> CREATE FUNCTION test=> NOTICE: DoAddPerson(4, 'Dubois') ConclusionL'opĂ©rateur C'est-Ă -dire que lorsqu'on Ă©crit: test=> tout se passe comme si on avait Ă©crit: test=> NOTICE: BuildPerson(2, 'Dupond') N'hĂ©sitez pas Ă me faire part de vos remarques, suggestions, et bien sĂ»r expĂ©rimentations autour de cet article :) — Michelle Baert — |
|||
© PostgreSQLFr, tous droits rĂ©servĂ©s.
Site déclaré à la CNIL sous le numéro 1074678, conformément à la Loi en vigueur.