Changeset 791
- Timestamp:
- 11/18/07 16:40:34 (1 year ago)
- Files:
-
- traduc/trunk/manuel/plpgsql.xml (modified) (149 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
traduc/trunk/manuel/plpgsql.xml
r782 r791 21 21 <listitem> 22 22 <para> 23 est utilisé pour créer des procédures fonctions et déclencheurs,23 est utilisé pour créer des fonctions standards et triggers, 24 24 </para> 25 25 </listitem> … … 31 31 <listitem> 32 32 <para> 33 pe uteffectuer des traitements complexes,33 permet d'effectuer des traitements complexes, 34 34 </para> 35 35 </listitem> … … 42 42 <listitem> 43 43 <para> 44 peut êtredéfini comme digne de confiance par le serveur,44 est défini comme digne de confiance par le serveur, 45 45 </para> 46 46 </listitem> … … 56 56 Les fonctions écrites en <application>PL/pgSQL</application> peuvent être 57 57 utilisées partout où une fonction intégrée peut l'être. 58 Par exemple, il est possible de créer des fonctions de traitement conditionnel59 co mplexes et, par la suite, de les utiliser pour définir des opérateurs ou60 de les utiliser dans des expressions d'index.58 Par exemple, il est possible de créer des fonctions complexes de traitement 59 conditionnel et, par la suite, de les utiliser pour définir des opérateurs 60 ou de les utiliser dans des expressions d'index. 61 61 </para> 62 62 … … 119 119 <para> 120 120 Les fonctions écrites en <application>PL/pgSQL</application> peuvent accepter 121 commeargument n'importe quel type de données supporté par le serveur, et121 en argument n'importe quel type de données supporté par le serveur, et 122 122 peuvent renvoyer un résultat de n'importe lequel de ces types. Elles peuvent 123 123 aussi accepter ou renvoyer n'importe quel type composite (type ligne) spécifié … … 130 130 131 131 <para> 132 Les fonctions <application>PL/pgSQL</application> peuvent aussi être déclarées comme133 acceptant et renvoyant les types <quote>polymorphes</quote>,134 <type>anyelement</type>, <type>anyarray</type>, <type>anynonarray</type> et <type>anyenum</type>. Le type de données réel 135 géré par une fonction polymorphe peut varier d'appel en appel (voir la136 <xref linkend="extend-types-polymorphic"/>).132 Les fonctions <application>PL/pgSQL</application> acceptent en entrée et 133 en sortie les types polymorphes <type>anyelement</type>, 134 <type>anyarray</type>, <type>anynonarray</type> et <type>anyenum</type>. 135 Le type de données réel géré par une fonction polymorphe peut varier 136 d'appel en appel (voir la <xref linkend="extend-types-polymorphic"/>). 137 137 Voir l'exemple de la <xref linkend="plpgsql-declaration-aliases"/>. 138 138 </para> 139 139 140 140 <para> 141 Les fonctions <application>PL/pgSQL</application> peuvent aussi être déclarées comme142 devant renvoyer un <quote>ensemble</quote> ou une table de n'importe lequel des143 type de données dont elles peuvent renvoyer une instance unique. De telles141 Les fonctions <application>PL/pgSQL</application> peuvent aussi renvoyer 142 un ensemble de lignes, une table ou n'importe lequel des type de données 143 dont elles peuvent renvoyer une instance unique. Ces 144 144 fonctions génèrent leur sortie en exécutant <literal>RETURN NEXT</literal> 145 145 pour chaque élément désiré de l'ensemble résultat ou en utilisant … … 157 157 avec des paramètres en sortie à la place de la spécification explicite 158 158 du code de retour. Ceci n'ajoute pas de fonctionnalité fondamentale au 159 langage mais c'est un moyen souvent agréable, spécialement pour retourner159 langage mais c'est un moyen agréable principalement pour renvoyer 160 160 plusieurs valeurs. 161 161 </para> … … 189 189 Chaque déclaration et chaque expression au sein du bloc est terminé par un 190 190 point-virgule. Un bloc qui apparaît à l'intérieur d'un autre bloc doit avoir 191 un point-virgule après <literal>END</literal> , comme montré ci-dessus ;191 un point-virgule après <literal>END</literal> (voir l'exemple ci-dessus) ; 192 192 néanmoins, le <literal>END</literal> final qui conclut le corps d'une fonction 193 193 n'a pas besoin de point-virgule. … … 197 197 <para> 198 198 Une erreur habituelle est d'écrire un point-virgule immédiatement 199 après <literal>BEGIN</literal>. C'est incorrect et a uracomme résultat199 après <literal>BEGIN</literal>. C'est incorrect et a comme résultat 200 200 une erreur de syntaxe. 201 201 </para> … … 206 206 identifier le bloc à utiliser dans une instruction <literal>EXIT</literal> 207 207 ou pour qualifier les noms de variable déclarées dans le bloc. Si un label 208 est donnéaprès <literal>END</literal>, il doit correspondre au label donné208 est écrit après <literal>END</literal>, il doit correspondre au label donné 209 209 au début du bloc. 210 210 </para> … … 213 213 Tous les mots clés sont insensibles à la casse. Les identifiants sont 214 214 convertis implicitement en minuscule sauf dans le cas de l'utilisation 215 de guillemets doubles , donc de la même façon que les commandes SQL216 habituelles.215 de guillemets doubles. Le comportement est donc identique à celui des 216 commandes SQL habituelles. 217 217 </para> 218 218 … … 231 231 Chaque expression de la section expression d'un bloc peut être un 232 232 <firstterm>sous-bloc</firstterm>. Les sous-blocs peuvent être utilisés pour 233 des groupements logiques ou pour localiser des variables locales àun petit groupe233 des groupements logiques ou pour situer des variables locales dans un petit groupe 234 234 d'instructions. Les variables déclarées dans un sous-bloc masquent toute 235 variable nommée de façon similaire d es blocs externes pendantla durée du236 sous-bloc. Cependant, vous pou bez accéder aux variables externes si vous237 qualifiez leur nom du label d ubloc. Par exemple :235 variable nommée de façon similaire dans les blocs externes pendant toute la durée du 236 sous-bloc. Cependant, vous pouvez accéder aux variables externes si vous 237 qualifiez leur nom du label de leur bloc. Par exemple : 238 238 <programlisting>CREATE FUNCTION une_fonction() RETURNS integer AS $$ 239 239 << blocexterne >> … … 263 263 <note> 264 264 <para> 265 Il existe un <quote>bloc externe</quote> caché entourrant le corps de265 Il existe un bloc externe caché entourant le corps de 266 266 toute fonction <application>PL/pgSQL</application>. Ce bloc fournit la 267 267 déclaration des paramètres de la fonction ainsi que quelques variables 268 spéciales comme <literal>FOUND</literal> (voir 268 spéciales comme <literal>FOUND</literal> (voir la 269 269 <xref linkend="plpgsql-statements-diagnostics"/>). Le bloc externe a pour 270 label le nom de la fonction , ceci signifiantque les paramètres et les271 variables spéciales peuvent être qualifié es du nom de la fonction.270 label le nom de la fonction. Cela a pour conséquence que les paramètres et les 271 variables spéciales peuvent être qualifiés du nom de la fonction. 272 272 </para> 273 273 </note> … … 279 279 contrôle des transactions. Les <command>BEGIN</command>/<command>END</command> de 280 280 <application>PL/pgSQL</application> ne servent qu'au groupement ; ils ne débutent 281 ni ne terminent une transaction. Les procédures fonctions et déclencheurs281 ni ne terminent une transaction. Les fonctions standards et les fonctions triggers 282 282 sont toujours exécutées à l'intérieur d'une transaction établie par une 283 283 requête extérieure — ils ne peuvent pas être utilisés pour commencer … … 298 298 La seule exception est que la variable de boucle d'une boucle <literal>FOR</literal> 299 299 effectuant une itération sur des valeurs entières est automatiquement déclarée 300 comme variable entière .300 comme variable entière (type integer). 301 301 </para> 302 302 … … 308 308 309 309 <para> 310 Quelques exemples de déclaration sde variables :310 Quelques exemples de déclaration de variables : 311 311 <programlisting>id_utilisateur integer; 312 312 quantité numeric(5); … … 322 322 <synopsis><replaceable>nom</replaceable> <optional> CONSTANT </optional> <replaceable>type</replaceable> <optional> NOT NULL </optional> <optional> { DEFAULT | := } <replaceable>expression</replaceable> </optional>; 323 323 </synopsis> 324 La clause <literal>DEFAULT</literal>, si indiquée, spécifie la valeur initiale 325 assignée à la variable quand on entre dans le bloc. 326 Si la clause <literal>DEFAULT</literal> n'est pas indiquée, la variable est initialisée 327 à la valeur <acronym>SQL</acronym> NULL. 328 L'option <literal>CONSTANT</literal> empêche l'assignation de la variable, de sorte que 329 sa valeur reste constante pour la durée du bloc. 330 Si <literal>NOT NULL</literal> est spécifié, l'assignement d'une valeur NULL aboutira à 331 une erreur d'exécution. Les valeurs par défaut de toutes les variables déclarées 332 <literal>NOT NULL</literal> doivent être spécifiées non NULL. 324 La clause <literal>DEFAULT</literal>, si indiquée, spécifie la valeur 325 initiale affectée à la variable quand on entre dans le bloc. 326 Si la clause <literal>DEFAULT</literal> n'est pas indiquée, la variable 327 est initialisée à la valeur <acronym>SQL</acronym> NULL. 328 L'option <literal>CONSTANT</literal> empêche la modification de la 329 variable, de sorte que sa valeur reste constante pour la durée du bloc. 330 Si <literal>NOT NULL</literal> est spécifié, l'affectation d'une valeur 331 NULL aboutira à une erreur d'exécution. Les valeurs par défaut de toutes 332 les variables déclarées <literal>NOT NULL</literal> doivent être 333 précisées, donc non NULL. 333 334 </para> 334 335 … … 336 337 La valeur par défaut d'une variable est évaluée et affectée à la variable 337 338 à chaque entrée du bloc (pas seulement une fois lors de l'appel de la 338 fonction . Ainsi, par exemple,339 l'assignation de <literal>now()</literal> à une variable de type340 <type>timestamp</type> donnera à la variable l'heure de l'appel de la fonction341 courante, et non l'heure au moment oùla fonction a été précompilée.339 fonction). Ainsi, par exemple, l'affectation de <literal>now()</literal> 340 à une variable de type <type>timestamp</type> donnera à la variable 341 l'heure de l'appel de la fonction courante, et non l'heure au moment où 342 la fonction a été précompilée. 342 343 </para> 343 344 … … 372 373 END; 373 374 </programlisting> 374 L'autre façon, la seule disponible pour les versions antérieures de375 L'autre façon, la seule disponible pour les versions antérieures à 375 376 <productname>PostgreSQL</productname> 8.0, est de déclarer explicitement 376 un alias en utilisant la syntaxe de déclaration 377 un alias en utilisant la syntaxe de déclaration : 377 378 378 379 <synopsis><replaceable>nom</replaceable> ALIAS FOR $<replaceable>n</replaceable>; 379 380 </synopsis> 380 381 381 Le même exemple dans ce style ressemble à :382 Le même exemple dans ce style ressemble à ceci : 382 383 <programlisting>CREATE FUNCTION taxe_ventes(real) RETURNS real AS $$ 383 384 DECLARE … … 393 394 <para> 394 395 Ces deux exemples ne sont pas complètement identiques. Dans le premier cas, 395 <literal>sous_total</literal> oeut être référencé comme396 <literal>sous_total</literal> peut être référencé comme 396 397 <literal>taxe_ventes.sous_total</literal>, alors que ce n'est pas possible 397 398 dans le second cas. (Si nous avions attaché un label au bloc, … … 425 426 <literal>$<replaceable>n</replaceable></literal> et des alias optionnels 426 427 de la même façon que les paramètres en entrée. Un paramètre en sortie est 427 réellementune variable qui commence avec la valeur NULL ; il428 une variable qui commence avec la valeur NULL ; il 428 429 devrait se voir attribuer une valeur lors de l'exécution de la fonction. 429 430 La valeur finale du paramètre est ce qui est renvoyée. Par exemple, 430 l'exemple sales-tax aurait pu être écritde cette façon :431 l'exemple taxe_ventes peut s'écrire de cette façon : 431 432 432 433 <programlisting>CREATE FUNCTION taxe_ventes(sous_total real, OUT taxe real) AS $$ … … 437 438 </programlisting> 438 439 439 Notez que nous avons omis <literal>RETURNS real</literal> — nous aurions440 Notez que nous avons omis <literal>RETURNS real</literal>. Nous aurions 440 441 pu l'inclure mais cela aurait été redondant. 441 442 </para> … … 460 461 461 462 <para> 462 Lorsque le type de retour d'une fonction <application>PL/pgSQL</application> est déclaré comme type polymorphe (<type>anyelement</type>, 463 <type>anyarray</type>, <type>anynonarray</type> et <type>anyenum</type>), un paramètre spécial <literal>$0</literal> est créé. 463 Lorsque le type de retour d'une fonction <application>PL/pgSQL</application> 464 est déclaré comme type polymorphe (<type>anyelement</type>, 465 <type>anyarray</type>, <type>anynonarray</type> et <type>anyenum</type>), un 466 paramètre spécial <literal>$0</literal> est créé. 464 467 Son type de donnée est le type effectif de retour de la fonction, déduit d'après 465 les types d'entrée (voir la <xref linkend="extend-types-polymorphic"/>).468 les types en entrée (voir la <xref linkend="extend-types-polymorphic"/>). 466 469 Ceci permet à la fonction d'accéder à son type de retour réel comme on le voit ici 467 470 avec la <xref linkend="plpgsql-declaration-type"/>. … … 470 473 bien que cela ne soit pas requis. On peut aussi donner un alias à 471 474 <literal>$0</literal>. Par exemple, cette fonction s'exécute comme un 472 opérateur <literal>+</literal> pour n'importe quel type de données .475 opérateur <literal>+</literal> pour n'importe quel type de données : 473 476 <programlisting>CREATE FUNCTION ajoute_trois_valeurs(v1 anyelement, v2 anyelement, v3 anyelement) 474 477 RETURNS anyelement AS $$ … … 484 487 485 488 <para> 486 Le même effet peut être obtenu en déclarant un ou plusieurs paramètres en487 sortie de types polymorphiques. Dans ce489 Le même effet peut être obtenu en déclarant un ou plusieurs paramètres 490 polymorphes en sortie de types. Dans ce 488 491 cas, le paramètre spécial <literal>$0</literal> n'est pas utilisé ; 489 492 les paramètres en sortie servent ce même but. Par exemple : … … 509 512 <literal>%TYPE</literal> fournit le type de données d'une variable ou d'une 510 513 colonne de table. Vous pouvez l'utiliser pour déclarer des variables qui 511 contiendront des valeurs de base sde données. Par exemple, disons que vous514 contiendront des valeurs de base de données. Par exemple, disons que vous 512 515 avez une colonne nommée <literal>id_utilisateur</literal> dans votre table 513 516 <literal>utilisateurs</literal>. Pour déclarer une variable du même type de … … 555 558 <para> 556 559 Une variable ligne peut être déclarée de façon à avoir le même type que les lignes 557 d'une table ou vue existante, en utilisant la notation558 <replaceable>nom_table</replaceable><literal>%ROWTYPE</literal> 559 ou elle peut être déclarée en donnant un nom de type composite (chaque table560 d'une table ou d'une vue existante, en utilisant la notation 561 <replaceable>nom_table</replaceable><literal>%ROWTYPE</literal>. 562 Elle peut aussi être déclarée en donnant un nom de type composite. Chaque table 560 563 ayant un type de données associé du même nom, il importe peu dans 561 564 <productname>PostgreSQL</productname> que vous écriviez <literal>%ROWTYPE</literal> ou pas. 562 Cependant la forme utilisant <literal>%ROWTYPE</literal> est plus portable).565 Cependant, la forme utilisant <literal>%ROWTYPE</literal> est plus portable. 563 566 </para> 564 567 565 568 <para> 566 569 Les paramètres d'une fonction peuvent être des types composites 567 (lignes complètes de tables). Ence cas, l'identifiant correspondant570 (lignes complètes de tables). Dans ce cas, l'identifiant correspondant 568 571 <literal>$<replaceable>n</replaceable></literal> sera une variable ligne à partir de laquelle 569 les champs peuvent être sélectionnés , par exemple <literal>$1.id_utilisateur</literal>.570 </para> 571 572 <para> 573 Seules les colonnes définies par l'utilisateur d'une ligne de tablesont accessibles572 les champs peuvent être sélectionnés avec la notation pointée, par exemple <literal>$1.id_utilisateur</literal>. 573 </para> 574 575 <para> 576 Seules les colonnes définies par l'utilisateur sont accessibles 574 577 dans une variable de type ligne, et non l'OID ou d'autres colonnes systèmes (parce que 575 578 la ligne pourrait être issue d'une vue). Les champs du type ligne héritent des tailles … … 606 609 607 610 <para> 608 Les variables record sont similaires aux variables de type ligne mais n'ont pas de 609 structure prédéfinie. Elles empruntent la structure effective de type ligne 610 de la ligne à laquelle elles sont assignées durant une commande <command>SELECT</command> or <command>FOR</command>. 611 La sous-structure d'une variable record peut changer à chaque fois qu'on l'assigne. 612 Une conséquence de cela est que jusqu'à ce qu'elle ait été assignée, elle n'a pas de 613 sous-structure, et toutes les tentatives pour accéder à un de ses champs 614 entraîneront une erreur d'exécution. 611 Les variables record sont similaires aux variables de type ligne mais n'ont 612 pas de structure prédéfinie. Elles empruntent la structure effective de 613 type ligne de la ligne à laquelle elles sont affectées durant une commande 614 <command>SELECT</command> ou <command>FOR</command>. La sous-structure d'une 615 variable record peut changer à chaque fois qu'on l'affecte. Une conséquence 616 de cela est qu'elle n'a pas de sous-structure jusqu'à ce qu'elle ait été 617 affectée, et toutes les tentatives pour accéder à un de ses champs 618 entraînent une erreur d'exécution. 615 619 </para> 616 620 … … 621 625 il ne s'agit pas tout à fait du même concept qu'une variable record, même si 622 626 une telle fonction peut aussi utiliser une variable record pour contenir son 623 résultat. Dans les deux cas la structure réelle de la ligne n'est pas connue quand627 résultat. Dans les deux cas, la structure réelle de la ligne n'est pas connue quand 624 628 la fonction est écrite mais, dans le cas d'une fonction renvoyant un type 625 629 <type>record</type>, la structure réelle est déterminée quand la requête appelante est … … 636 640 <para> 637 641 En utilisant la déclaration <literal>RENAME</literal>, vous pouvez changer le nom d'une variable, 638 d'un record ou d'un row (ligne). C'est particulièrement utile si642 d'un record ou d'un ligne (ROW). C'est particulièrement utile si 639 643 <varname>NEW</varname> ou <varname>OLD</varname> doivent 640 être référencés par un autre nom dans une procédure déclencheur. Voir644 être référencés par un autre nom dans une procédure trigger. Voir 641 645 aussi <literal>ALIAS</literal>. 642 646 </para> … … 671 675 </synopsis> 672 676 est traité par le moteur SQL principal. Bien qu'utilisant la commande 673 <command>SELECT</command> command, toute occurence denom de variable674 <application>PL/pgSQL</application> est remplacé e par des paramètres,675 comme expliqué en détail dans <xref linkend="plpgsql-var-subst"/>.676 Ce cipermet au plan de requête du <command>SELECT</command> d'être677 <command>SELECT</command>, tout nom de variable 678 <application>PL/pgSQL</application> est remplacé par des paramètres 679 (ceci est expliqué en détail dans la <xref linkend="plpgsql-var-subst"/>). 680 Cela permet au plan de requête du <command>SELECT</command> d'être 677 681 préparé une seule fois, puis d'être réutilisé pour les évaluations 678 682 suivantes avec différentes valeurs des variables. Du coup, ce qui arrive … … 686 690 ce qui se passe en arrière plan est ceci : 687 691 <programlisting> 688 PREPARE <replaceable>no _instruction</replaceable>(integer, integer) AS SELECT $1 < $2;692 PREPARE <replaceable>nom_instruction</replaceable>(integer, integer) AS SELECT $1 < $2; 689 693 </programlisting> 690 694 puis cette instruction préparée est exécutée (via <command>EXECUTE</command>) … … 693 697 en tant que valeurs des paramètres. Le plan de requête préparé de cette 694 698 façon est sauvegardé pour toute la durée de la connexion à la base, comme 695 le décrit <xref linkend="plpgsql-plan-caching"/>. Généralement, ces détails699 le décrit la <xref linkend="plpgsql-plan-caching"/>. Généralement, ces détails 696 700 ne sont pas importants pour un utilisateur de 697 701 <application>PL/pgSQL</application>, mais ils sont utiles à connaître … … 709 713 Tout ce qui n'est pas reconnu comme l'un de ces types d'instruction est présumé 710 714 être une commande SQL et est envoyé au moteur principal de bases de données pour 711 être exécutée comme décrit dans <xref linkend="plpgsql-statements-sql-noresult"/>712 et <xref linkend="plpgsql-statements-sql-onerow"/>.715 être exécutée comme décrit dans la <xref linkend="plpgsql-statements-sql-noresult"/> 716 et dans la <xref linkend="plpgsql-statements-sql-onerow"/>. 713 717 714 718 </para> 715 719 716 720 <sect2 id="plpgsql-statements-assignment"> 717 <title>A ssignation</title>718 719 <para> 720 L'a ssignation d'une valeur à une variable <application>PL/pgSQL</application>721 ou à un champ row/record est écriteainsi :721 <title>Affectation</title> 722 723 <para> 724 L'affectation d'une valeur à une variable <application>PL/pgSQL</application> 725 ou à un champ row/record s'écrit ainsi : 722 726 <synopsis><replaceable>variable</replaceable> := <replaceable>expression</replaceable>; 723 727 </synopsis> 724 Comme expliqué plus haut, l'expression dans une telle instruction est évaluée au728 Comme expliqué plus haut, l'expression dans cette instruction est évaluée au 725 729 moyen de la commande SQL <command>SELECT</command> envoyée au moteur principal de 726 730 bases de données. L'expression ne doit manier qu'une seule valeur. … … 733 737 par l'interpréteur <application>PL/pgSQL</application> en utilisant la fonction 734 738 d'écriture (output-function) du type du résultat, et la fonction d'entrée 735 (input-function) du type de la variable. Notez que cela p ourrait potentiellement739 (input-function) du type de la variable. Notez que cela peut 736 740 conduire à des erreurs d'exécution générées par la fonction d'entrée si la forme 737 de la chaîne de la valeur résultat n'est pas acceptable p ar la fonction d'entrée.741 de la chaîne de la valeur résultat n'est pas acceptable pour cette fonction. 738 742 </para> 739 743 740 744 <para> 741 745 Exemples : 742 <programlisting>tax := sous_total * 0.06;746 <programlisting>taxe := sous_total * 0.06; 743 747 mon_enregistrement.id_utilisateur := 20; 744 748 </programlisting> … … 761 765 puis la valeur actuelle de la variable est fournie comme valeur du 762 766 paramètre à l'exécution. C'est le traitement exact décrit précédemment pour 763 les expressions ; pour les détails, voir<xref767 les expressions. Pour les détails, voir la <xref 764 768 linkend="plpgsql-var-subst"/>. Par exemple, si vous écrivez 765 769 <programlisting>DECLARE … … 770 774 UPDATE matable SET val = val + delta WHERE id = cle; 771 775 </programlisting> 772 le texte de la commande envoyée par le moteur SQL ressemble ra à ceci776 le texte de la commande envoyée par le moteur SQL ressemble à ceci : 773 777 <programlisting> UPDATE matable SET val = val + $1 WHERE id = $2; 774 778 </programlisting> 775 Bien que vous n'ayez pas à y penser, il est utile de l asavoir pour mieux779 Bien que vous n'ayez pas à y penser, il est utile de le savoir pour mieux 776 780 comprendre les messages d'erreur de syntaxe. 777 781 </para> … … 779 783 <caution> 780 784 <para> 781 <application>PL/pgSQL</application> substitutera pourtout identifiant785 <application>PL/pgSQL</application> substitutera à tout identifiant 782 786 une variable déclarée de la fonction. Du coup, une mauvaise idée serait 783 787 d'utiliser un nom de variable identique à celui d'une table, d'une 784 788 colonne ou d'une fonction que vous avez besoin d'utiliser dans des 785 commandes de la fonction. Pour plus d'informations, voir <xref linkend="plpgsql-var-subst"/>.789 commandes de la fonction. Pour plus d'informations, voir la <xref linkend="plpgsql-var-subst"/>. 786 790 </para> 787 791 </caution> … … 792 796 ré-utilise ce plan lors des prochaines exécutions, pour la durée de vie 793 797 de la connexion. Les implications de ceci sont discutées en détail dans 794 <xref linkend="plpgsql-plan-caching"/>.795 </para> 796 797 <para> 798 Quelquefois, il est utile d'évaluer une expression ou une requête798 la <xref linkend="plpgsql-plan-caching"/>. 799 </para> 800 801 <para> 802 Parfois, il est utile d'évaluer une expression ou une requête 799 803 <command>SELECT</command> mais sans récupérer le résultat, par 800 804 exemple lors de l'appel d'une fonction qui a des effets de bord … … 813 817 Les variables <application>PL/pgSQL</application> seront substituées dans 814 818 la requête comme pour les commandes qui ne renvoient pas de résultat. Le 815 plan est mis en cache de la même façon. De plus, la variable spéciale819 plan est mis en cache de la même façon. La variable spéciale 816 820 <literal>FOUND</literal> est configurée à true si la requête a produit 817 au moins une ligne, false dans le cas contraire (voir 821 au moins une ligne, false dans le cas contraire (voir la 818 822 <xref linkend="plpgsql-statements-diagnostics"/>). 819 823 </para> … … 833 837 <para> 834 838 Un exemple : 835 <programlisting>PERFORM cre ate_mv('cs_session_page_requests_mv', my_query);839 <programlisting>PERFORM creer_vuemat('cs_session_page_requests_mv', ma_requete); 836 840 </programlisting> 837 841 </para> … … 864 868 865 869 où <replaceable>cible</replaceable> peut être une variable de type record, 866 row ou une liste de simplevariables ou de champs record/row séparées par870 row ou une liste de variables ou de champs record/row séparées par 867 871 des virgules. Les variables <application>PL/pgSQL</application> seront 868 872 substituées dans le reste de la requête, et le plan est mis en cache … … 913 917 <replaceable>cible</replaceable> sera configuré avec la première ligne 914 918 renvoyée par la requête ou à NULL si la requête n'a renvoyé aucune ligne. 915 (Notez que <quote>la première ligne</quote> n'est pas bien définie sauf919 (Notez que <quote>la première ligne</quote> n'est bien définie que 916 920 si vous avez utilisé <literal>ORDER BY</literal>.) Toute ligne résultat 917 après la première ligne est annulée. Vous pouvez vérifier la va riable918 spéciale <literal>FOUND</literal> (voir921 après la première ligne est annulée. Vous pouvez vérifier la valeur de la 922 variable spéciale <literal>FOUND</literal> (voir la 919 923 <xref linkend="plpgsql-statements-diagnostics"/>) pour déterminer si une 920 924 ligne a été renvoyée : … … 926 930 </programlisting> 927 931 928 Si l'option <literal>STRICT</literal> est indiquée, la requête doit exactement929 renvoyer une ligne. Dans le cas contraire, une erreur sera rapportée à932 Si l'option <literal>STRICT</literal> est indiquée, la requête doit 933 renvoyer exactement une ligne. Dans le cas contraire, une erreur sera rapportée à 930 934 l'exécution, soit <literal>NO_DATA_FOUND</literal> (aucune ligne) soit 931 935 <literal>TOO_MANY_ROWS</literal> (plus d'une ligne). Vous pouvez utiliser … … 964 968 <para> 965 969 Pour gérer les cas où vous avez besoin de traiter plusieurs lignes de 966 résultat à partir d'une requête SQL, voir <xref linkend="plpgsql-records-iterating"/>.970 résultat à partir d'une requête SQL, voir la <xref linkend="plpgsql-records-iterating"/>. 967 971 </para> 968 972 … … 973 977 974 978 <para> 975 Souvent vous voudrez générer des commandes dynamiques dans vos fonctions976 <application>PL/pgSQL</application>, c'est-à-dire des commandes979 Créer dynamique des requêtes SQL est un besoin habituel dans les fonctions 980 <application>PL/pgSQL</application>, par exemple des requêtes 977 981 qui impliquent différentes tables ou différents types de données à chaque 978 982 fois qu'elles sont exécutées. Les tentatives normales de 979 983 <application>PL/pgSQL</application> pour garder en cache les planifications 980 des commandes (voir <xref linkend="plpgsql-plan-caching"/>) ne984 des commandes (voir la <xref linkend="plpgsql-plan-caching"/>) ne 981 985 fonctionneront pas dans de tels scénarios. Pour gérer ce type 982 de problème, l'instruction <command>EXECUTE</command> est fournie :986 de problème, l'instruction <command>EXECUTE</command> est proposée : 983 987 984 988 <synopsis>EXECUTE <replaceable class="command">chaîne-commande</replaceable> <optional> INTO <optional>STRICT</optional> <replaceable>cible</replaceable> </optional>; … … 986 990 987 991 où <replaceable>chaîne-commande</replaceable> est une expression manipulant 988 une chaîne (de type <type>text</type>) contenant la commande à être exécutée989 et <replaceable>cible</replaceable> est une variable record ou ligne ou990 une liste de variables simples ou de champs de lignes/enregistrements992 une chaîne (de type <type>text</type>) contenant la commande à exécuter 993 et où<replaceable>cible</replaceable> est une variable record ou ligne ou 994 même une liste de variables simples ou de champs de lignes/enregistrements 991 995 séparées par des virgules. 992 996 </para> … … 1003 1007 <command>EXECUTE</command>. À la 1004 1008 place, la commande est préparée à chaque fois que l'instruction est lancée. 1005 La chaîne commande peut être dynamiquement crééeà l'intérieur de la1009 La chaîne commande peut être créée dynamiquement à l'intérieur de la 1006 1010 fonction pour agir sur des tables ou colonnes différentes. 1007 1011 </para> 1008 1012 1009 1013 <para> 1010 La clause <literal>INTO</literal> spécifie où les résultats d'une commande1011 SQL renvoyant des lignes devraient être affectés. Si une ligne ou une1014 La clause <literal>INTO</literal> spécifie où devraient être affectés les 1015 résultats d'une commande SQL renvoyant des lignes. Si une ligne ou une 1012 1016 liste de variable est fournie, elle doit correspondre exactement à la 1013 1017 structure des résultats de la requête (quand 1014 une variable de type record est utilisée, elle se configurera toute seule1018 une variable de type record est utilisée, elle sera automatiquement typée 1015 1019 pour correspondre à la structure du résultat). Si plusieurs lignes sont 1016 1020 renvoyées, alors seule la première sera assignée à la variable … … 1018 1022 à la variable <literal>INTO</literal>. Si aucune clause 1019 1023 <literal>INTO</literal> n'est spécifiée, les résultats de la requête sont 1020 annulées.1024 ignorés. 1021 1025 </para> 1022 1026 … … 1040 1044 par le serveur <productname>PostgreSQL</productname>. L'instruction 1041 1045 <command>EXECUTE</command> du serveur ne peut pas être utilisée directement 1042 dans les fonctions <application>PL/pgSQL</application> (etn'est pas1043 nécessaire ).1046 dans les fonctions <application>PL/pgSQL</application>. En fait, elle n'est pas 1047 nécessaire. 1044 1048 </para> 1045 1049 </note> … … 1064 1068 pas besoin d'être doublés) : 1065 1069 <programlisting>EXECUTE 'UPDATE tbl SET ' 1066 || quote_ident( colname)1070 || quote_ident(nom_colonne) 1067 1071 || ' = ' 1068 || quote_literal(n ewvalue)1069 || ' WHERE key= '1070 || quote_literal( keyvalue);</programlisting>1072 || quote_literal(nouvelle_valeur) 1073 || ' WHERE cle = ' 1074 || quote_literal(valeur_cle);</programlisting> 1071 1075 </para> 1072 1076 … … 1085 1089 <function>quote_ident</function> et <function>quote_literal</function>. 1086 1090 Pour plus de sûreté, les expressions contenant 1087 les identifiants des colonnes et des tables doivent être passé s à la1088 fonction <function>quote_ident</function>. Les expressions contenant les1089 valeurs de vant être des chaînes dans la commande construite devraient être1090 passées à <function>quote_literal</function>. Les deux font les étapes1091 les identifiants des colonnes et des tables doivent être passées à la 1092 fonction <function>quote_ident</function>. Les expressions contenant des 1093 valeurs de type chaîne de caractères doivent être 1094 passées à <function>quote_literal</function>. Ce sont les étapes 1091 1095 appropriées pour renvoyer le texte en entrée entouré par des guillemets 1092 doubles ou simples respectivement, avec tout caractère intégré spécial 1093 proprement échappé. 1096 doubles ou simples respectivement, en échappant tout caractère spécial. 1094 1097 </para> 1095 1098 1096 1099 <para> 1097 1100 Notez que les guillemets dollar sont souvent utiles pour placer un texte 1098 fixe entre guillemets. Il serait une très mauvaise idée d'essayer de1099 faire l'exempleci-dessus de cette façon :1101 fixe entre guillemets. Ce serait une très mauvaise idée d'écrire l'exemple 1102 ci-dessus de cette façon : 1100 1103 <programlisting> EXECUTE 'UPDATE tbl SET ' 1101 || quote_ident( colname)1104 || quote_ident(nom_colonne) 1102 1105 || ' = $$' 1103 || n ewvalue1104 || '$$ WHERE key= '1105 || quote_literal( keyvalue);</programlisting>1106 || nouvelle_valeur 1107 || '$$ WHERE cle = ' 1108 || quote_literal(valeur_cle);</programlisting> 1106 1109 car cela casserait si le contenu de <literal>newvalue</literal> pouvait contenir 1107 <literal>$$</literal>. La même objection s'applique raità tout délimiteur dollar1110 <literal>$$</literal>. La même objection s'applique à tout délimiteur dollar 1108 1111 que vous pourriez choisir. Donc, pour mettre un texte inconnu entre 1109 1112 guillemets de façon sûr, vous <emphasis>devez</emphasis> utiliser … … 1123 1126 1124 1127 <para> 1125 Il y a plusieurs moyen de déterminer l'effet d'une commande. La première méthode 1126 est d'utiliser <command>GET DIAGNOSTICS</command>, qui a la forme 1127 suivante : 1128 Il y a plusieurs moyens pour déterminer l'effet d'une commande. La première méthode 1129 est d'utiliser <command>GET DIAGNOSTICS</command> : 1128 1130 1129 1131 <synopsis>GET DIAGNOSTICS <replaceable>variable</replaceable> = <replaceable>élément</replaceable> <optional> , ... </optional> ; 1130 1132 </synopsis> 1131 1133 1132 Cette commande permet la récupération des indicateurs d e l'état du système. Chaque1134 Cette commande permet la récupération des indicateurs d'état du système. Chaque 1133 1135 <replaceable>élément</replaceable> est un mot clé identifiant une valeur d'état devant 1134 être a ssignée à la variable indiquée (qui devrait être du bon type de donnée1135 pour pouvoir la recevoir.) Les items d'état actuellement disponibles sont1136 être affectée à la variable indiquée (qui doit être du bon type de donnée 1137 pour que l'affectation puisse se faire sans erreur.) Les éléments d'état actuellement disponibles sont 1136 1138 <varname>ROW_COUNT</varname>, le nombre de lignes traitées par la dernière commande 1137 1139 <acronym>SQL</acronym> envoyée au moteur <acronym>SQL</acronym>, et … … 1144 1146 <para> 1145 1147 Exemple : 1146 <programlisting>GET DIAGNOSTICS var_ integer = ROW_COUNT;1147 </programlisting> 1148 </para> 1149 1150 <para> 1151 La seconde méthode p ourdéterminer les effets d'une commande est la variable1148 <programlisting>GET DIAGNOSTICS var_entier = ROW_COUNT; 1149 </programlisting> 1150 </para> 1151 1152 <para> 1153 La seconde méthode permettant de déterminer les effets d'une commande est la variable 1152 1154 spéciale nommée <literal>FOUND</literal> de type <type>boolean</type>. 1153 <literal>FOUND</literal> commence par être false danschaque fonction1154 <application>PL/pgSQL</application>. Elle est positionnée par chacun edes types1155 d'instructions suivants .1155 La variable <literal>FOUND</literal> est initialisée à false au début de chaque fonction 1156 <application>PL/pgSQL</application>. Elle est positionnée par chacun des types 1157 d'instructions suivants : 1156 1158 <itemizedlist> 1157 1159 <listitem> … … 1165 1167 <para> 1166 1168 Une instruction <command>PERFORM</command> positionne <literal>FOUND</literal> 1167 à true si elle produit (rejette) une ou plusieurs lignes, fauxsi aucune ligne n'est1169 à true si elle renvoie une ou plusieurs lignes, false si aucune ligne n'est 1168 1170 produite. 1169 1171 </para> … … 1185 1187 <para> 1186 1188 Une instruction <command>MOVE</command> initialise 1187 <literal>FOUND</literal> à true si ilrepositionne le curseur1188 avec succès. Dans le cas contraire, ille positionne à false.1189 <literal>FOUND</literal> à true si elle repositionne le curseur 1190 avec succès. Dans le cas contraire, elle le positionne à false. 1189 1191 </para> 1190 1192 </listitem> … … 1197 1199 <command>FOR</command> record-set, 1198 1200 et <command>FOR</command> record-set dynamique). <literal>FOUND</literal> 1199 n'est positionné de cette façon que quand la boucle <command>FOR</command>1201 n'est positionnée de cette façon que quand la boucle <command>FOR</command> 1200 1202 s'achève ; 1201 1203 dans l'exécution de la chaîne, <literal>FOUND</literal> 1202 n'est pas modifiée par l'instruction <command>FOR</command>, bien qu' il1204 n'est pas modifiée par l'instruction <command>FOR</command>, bien qu'elle 1203 1205 puisse être modifié par l'exécution d'autres instructions situées 1204 1206 dans le corps de la boucle. … … 1209 1211 <literal>FOUND</literal> est une variable locale à l'intérieur de chaque 1210 1212 fonction <application>PL/pgSQL</application> ; chaque changement qui 1211 y est fait n'affecte que la fonction courante.1213 y est fait n'affecte que la fonction en cours. 1212 1214 </para> 1213 1215 … … 1219 1221 <para> 1220 1222 Quelque fois, une instruction qui ne fait rien est utile. Par exemple, 1221 il indique qu'une partie de la chaîne if/then/elseest délibérément1223 elle indique qu'une partie de la chaîne <command>IF</command>/<command>THEN</command>/<command>ELSE</command> est délibérément 1222 1224 vide. Pour cela, utilisez l'instruction : 1223 1225 … … 1239 1241 WHEN division_by_zero THEN -- ignore l'erreur 1240 1242 END;</programlisting> 1241 Ce qui est préférable est une histoirede goût.1243 Ce qui est préférable est une question de goût. 1242 1244 </para> 1243 1245 … … 1288 1290 <para> 1289 1291 Lorsqu'elle renvoie un type scalaire, n'importe quelle expression peut être 1290 utilisée. Le résultat de l'expression sera automatiquement transtypévers le type1291 de retour de la fonction, comme décrit pour les a ssignations. Pour renvoyer une1292 utilisée. Le résultat de l'expression sera automatiquement converti vers le type 1293 de retour de la fonction, comme décrit pour les affectations. Pour renvoyer une 1292 1294 valeur composite (ligne), vous devez écrire une variable record ou ligne comme 1293 1295 <replaceable>expression</replaceable>. … … 1303 1305 Si vous déclarez que la fonction renvoie <type>void</type>, une 1304 1306 instruction <command>RETURN</command> peut être utilisée pour quitter 1305 rapidement la fonction ; mais n'écrivez pas uneexpression après1307 rapidement la fonction ; mais n'écrivez pas d'expression après 1306 1308 <command>RETURN</command>. 1307 1309 </para> … … 1311 1313 Si le contrôle atteint la fin du bloc de haut niveau de la fonction, 1312 1314 sans parvenir à une instruction <command>RETURN</command>, une erreur 1313 d'exécution survien dra. Néanmoins, cette restriction ne s'applique pas1315 d'exécution survient. Néanmoins, cette restriction ne s'applique pas 1314 1316 aux fonctions sans paramètre de sortie et aux fonctions renvoyant 1315 1317 <type>void</type>. Dans ces cas, une instruction … … 1349 1351 requête à l'ensemble des résultats de la fonction. <command>RETURN 1350 1352 NEXT</command> et <command>RETURN QUERY</command> peuvent être 1351 utilisés dans la même fonction SRF, auquel cas leurs résultats seront1353 utilisés dans la même fonction, auquel cas leurs résultats seront 1352 1354 concaténées. 1353 1355 </para> … … 1361 1363 plusieurs commandes <command>RETURN NEXT</command> et/ou <command>RETURN 1362 1364 QUERY</command> successives sont exécutées, l'ensemble de résultats 1363 augmente ra. Un <command>RETURN</command> final, sans argument, permet1364 de quitter la fonction (mais vous pouvez aussi continuer jusqu'à la fin1365 de la fonction ).1365 augmente. Un <command>RETURN</command>, sans argument, permet 1366 de quitter la fonction mais vous pouvez aussi continuer jusqu'à la fin 1367 de la fonction. 1366 1368 </para> 1367 1369 … … 1384 1386 1385 1387 <programlisting> 1386 CREATE TABLE foo (fooid INT, foosubid INT, foonameTEXT);1387 INSERT INTO foo VALUES (1, 2, 'three');1388 INSERT INTO fooVALUES (4, 5, 'six');1389 1390 CREATE OR REPLACE FUNCTION getAllFoo() RETURNS SETOF foo AS1388 CREATE TABLE truc (id_truc INT, sousid_truc INT, nom_truc TEXT); 1389 INSERT INTO truc VALUES (1, 2, 'trois'); 1390 INSERT INTO truc VALUES (4, 5, 'six'); 1391 1392 CREATE OR REPLACE FUNCTION obtenirTousLesTrucs() RETURNS SETOF foo AS 1391 1393 $BODY$ 1392 1394 DECLARE 1393 r foo%rowtype;1395 r truc%rowtype; 1394 1396 BEGIN 1395 FOR r IN SELECT * FROM foo1396 WHERE fooid> 01397 FOR r IN SELECT * FROM truc 1398 WHERE id_truc > 0 1397 1399 LOOP 1398 -- can do some processing here1399 RETURN NEXT r; -- re turn next row ofSELECT1400 -- quelques traitements 1401 RETURN NEXT r; -- renvoie la ligne courante du SELECT 1400 1402 END LOOP; 1401 1403 RETURN; … … 1404 1406 LANGUAGE 'plpgsql' ; 1405 1407 1406 SELECT * FROM getallfoo();1408 SELECT * FROM obtenirTousLesTrucs(); 1407 1409 </programlisting> 1408 1410 … … 1417 1419 L'implémentation actuelle de <command>RETURN NEXT</command> et de 1418 1420 <command>RETURN QUERY</command> pour 1419 <application>PL/pgSQL</application> emmagasine la totalité de l'ensemble des1421 <application>PL/pgSQL</application> récupère la totalité de l'ensemble des 1420 1422 résultats avant 1421 1423 d'effectuer le retour de la fonction, comme vu plus haut. Cela signifie que … … 1423 1425 très grande, les performances peuvent être faibles : les données seront 1424 1426 écrites sur le disque pour éviter un épuisement de la mémoire mais la fonction 1425 en elle-même ne renverra rien jusqu'à ce que l'ensemble des résultats1426 entier soit généré. Une version future de <application>PL/pgSQL</application> pourra1427 permettr eaux utilisateurs de définir des fonctions renvoyant des ensembles qui1427 en elle-même ne renverra rien jusqu'à ce que l'ensemble complet des résultats 1428 soit généré. Une version future de <application>PL/pgSQL</application> 1429 permettra aux utilisateurs de définir des fonctions renvoyant des ensembles qui 1428 1430 n'auront pas cette limitation. Actuellement, le point auquel les données commencent 1429 1431 à être écrites sur le disque est contrôlé par la variable de configuration 1430 1432 <xref linkend="guc-work-mem"/>. Les administrateurs 1431 1433 ayant une mémoire suffisante pour enregistrer des ensembles de résultats 1432 plus importants en mémoire d evraient envisager l'augmentation de ce1434 plus importants en mémoire doiven

