|
||||
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.