PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 17/12/2013 14:44:29

Xav1er
Membre

[] smallint en paramètre in out d'une fonction

bonjour,

Je voudrais migrer une fonction Oracle vers Pgsql.
La fonction a des paramètres in out, dont un tableau d'entiers.

Pour la faire fonctionner sous Oracle, j'avais créé un package pour pouvoir passer un tableau d'entiers dont voici le descriptif :

CREATE OR REPLACE
PACKAGE PCK_LEP IS

  TYPE TP$TABLE IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;

  PROCEDURE P_LEP(LK$DT1 VARCHAR2, LK$DT2 VARCHAR2) ;

  FUNCTION MAJ_LEP (LK$LEP  LEP%ROWTYPE,
					LK$LISTE    TP$TABLE)
					RETURN NUMBER;
  
  FUNCTION PEC_LEP (  LK$TP_E NUMBER,
                      LK$HR_E NUMBER,
                      LK$LEP IN OUT LEP%ROWTYPE,
                      LK$LG1 IN OUT NUMBER,
                      LK$LG2 IN OUT NUMBER,
                      LK$LISTE IN OUT TP$TABLE)
				RETURN NUMBER;
END;

Le problème que je rencontre est que je ne sais pas comment migrer PEC_LEP, pg n'accepte pas [] smallint en in out ...
Y a t'il une alternative ?

Hors ligne

#2 18/12/2013 00:13:10

gleu
Administrateur

Re : [] smallint en paramètre in out d'une fonction

Quelle déclaration faites-vous pour cette fonction ? et quelle erreur renvoit-il ?

Hors ligne

#3 18/12/2013 01:47:00

Xav1er
Membre

Re : [] smallint en paramètre in out d'une fonction

Bonsoir,

Voilà ce que j'obtiens :

CREATE OR REPLACE FUNCTION PEC_LEP (LK$TP_E INTEGER,
                      LK$HR_E INTEGER,
                      LK$LEP IN OUT LEP,
                      LK$LG1 IN OUT INTEGER,
                      LK$LG2 IN OUT INTEGER,
                      LK$LISTE IN OUT SMALLINT[])
  RETURNS INTEGER AS
...


ERREUR:  le type de résultat de la fonction doit être record à cause des paramètres OUT

********** Erreur **********

ERREUR: le type de résultat de la fonction doit être record à cause des paramètres OUT
État SQL :42P13

Je débute en pgsql, et je ne saisis pas comment il faut mettre les paramètres ...

Hors ligne

#4 18/12/2013 16:40:48

gleu
Administrateur

Re : [] smallint en paramètre in out d'une fonction

Vous ne pouvez pas utiliser la clause RETURNS étant donné que vous utilisez des paramètres en INOUT. Autre chose, il n'y a pas d'espace entre IN et OUT.

Hors ligne

#5 22/12/2013 11:13:18

Xav1er
Membre

Re : [] smallint en paramètre in out d'une fonction

Merci !!! wink

Ça fonctionne cool

Hors ligne

#6 17/01/2014 17:40:12

Xav1er
Membre

Re : [] smallint en paramètre in out d'une fonction

En fait, j'ai quand même un souci : les champs INOUT ne sont pas modifiés. Ils sont juste fournis en copie dans la variable dans le RETURN ...

CREATE OR REPLACE FUNCTION p_test(test character varying)
  RETURNS void AS
$BODY$
DECLARE 
	LC$test		numeric:=0;
	cd_ret2 varchar;

BEGIN
	CD_RET2:=f_test2 (LC$test);		
	raise notice 'Valeur : %',LC$test;
	return;
END ;
$BODY$
  LANGUAGE plpgsql VOLATILE;


CREATE OR REPLACE FUNCTION f_test2(INOUT ma_var numeric)
  RETURNS numeric AS
$BODY$
DECLARE
  
BEGIN

ma_var:=ma_var+1;

END ;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

Donne

select p_test (null);

NOTICE:  Valeur : 0
NOTICE:  Valeur : 0
NOTICE:  Retour : 1

Si j'ai plein de variables en entrée, le type en sortie est "record", que je peux récupérer en varchar par exemple.

Mais comment remettre les variables modifiées dans celles que j'avais fournies en paramètre ?
En gros, si je fais un F_calcul (Var1, Var2, Var3, Var4, Var5)
je voudais que mes variables Var1 à Var5 soient modifiées. Sous Oracle, il n'y avait besoin d'aucune manipulation mais je suis prêt à rajouter quelques instructions ... neutral

Hors ligne

#7 18/01/2014 00:45:13

gleu
Administrateur

Re : [] smallint en paramètre in out d'une fonction

La valeur que vous testez est la valeur en entrée, pas la valeur en sortie. Sur votre fonction p_test, La valeur renvoyée par la fonction f_test2 est stockée dans CD_RET2. Autrement dit, vous devriez avoir :

CD_RET2:=f_test2 (LC$test);
raise notice 'Valeur : %',CD_RET2;

Attention que vous êtes dans le cadre d'une base de données. Du coup :

CD_RET2:=f_test2 (LC$test);

est équivalent à

SELECT INTO CD_RET2 f_test2 (LC$test);

ce qui donne plus de sens au fait que le retour est dans CD_RET2 et non pas dans LC$test.

Hors ligne

#8 20/01/2014 11:19:42

Xav1er
Membre

Re : [] smallint en paramètre in out d'une fonction

Mais comment faire si la fonction a en paramètre plusieurs variables INOUT ?
Pgsql dit qu'il faut que le retour soit de type record. Comment alors transférer les données "record" dans les champs initiaux ?
concrètement,
SELECT INTO CD_RET2  F_calcul (Var1, Var2, Var3, Var4, Var5);
comment faire passer dans var1, var2, ... ce qui est dans le record CD_RET2 ?

Hors ligne

#9 22/01/2014 00:40:36

gleu
Administrateur

Re : [] smallint en paramètre in out d'une fonction

Mais comment faire si la fonction a en paramètre plusieurs variables INOUT ?

Indiquez les différentes variables (une par colonne récupérée), ie : SELECT INTO CD_RET1, CD_RET2, CD_RET3 F_calcul(...);

comment faire passer dans var1, var2, ... ce qui est dans le record CD_RET2 ?

SELECT INTO Var1, Var2, Var3, Var4, Var5  F_calcul (Var1, Var2, Var3, Var4, Var5);

J'ai l'impression que vous prenez les paramètres INOUT pour des paramètres fournies par référence. Ce n'est clairement pas le cas. Ça n'aurait aucun sens au niveau d'une connexion SQL.

Hors ligne

#10 28/01/2014 16:09:00

Xav1er
Membre

Re : [] smallint en paramètre in out d'une fonction

Oui, c'est ça, je voudrais utiliser certaines fonctions pour des traitements.
C'est certain que je m'éloigne de l'esprit de l'origine des fonctions en SQL.

J'en utilise certaines pour faire des traitements qui auraient aussi bien pu être écrits dans d'autres langages.
Mais ça fonctionnait très bien avec Oracle.

Et j'ai toujours une erreur :

ERREUR: syntaxe en entrée invalide pour le type numeric : « (13,6,toto) »
État SQL :22P02
select into cd_ret1 , cd_ret2, cd_char  titi.f_test3 ( cd_ret1 , cd_ret2, cd_char ) ;

Hors ligne

#11 29/01/2014 01:15:23

gleu
Administrateur

Re : [] smallint en paramètre in out d'une fonction

Quel est la définition de f_test3 ?

Hors ligne

#12 29/01/2014 12:20:58

Xav1er
Membre

Re : [] smallint en paramètre in out d'une fonction

CREATE OR REPLACE FUNCTION titi.f_test3(INOUT ma_var2 numeric, INOUT ma_var numeric, INOUT ma_var3 character varying)
  RETURNS record AS
$BODY$
DECLARE
  
BEGIN

ma_var3:='toto';
ma_var:=ma_var+1;
ma_var2:=ma_var2+ma_var;

END ;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

(J'ai laissé volatile pour les tests ; une telle fonction devrait être IMMUTABLE si j'ai bien compris la doc, mais j'ai laissé par défaut pour mes tests).

Hors ligne

#13 29/01/2014 23:31:56

gleu
Administrateur

Re : [] smallint en paramètre in out d'une fonction

Comme vous renvoyez plusieurs colonnes, vous devez faire un :

select into cd_ret1 , cd_ret2, cd_char * FROM titi.f_test3 ( cd_ret1 , cd_ret2, cd_char ) ;

Hors ligne

#14 30/01/2014 11:33:24

Xav1er
Membre

Re : [] smallint en paramètre in out d'une fonction

Ah, oui, comme ça, ça fonctionne.
On progresse, mais j'ai un nouveau problème.
Ma fonction Oracle avait plusieurs paramètres IN OUT en entrée dont 1 de type ROWTYPE.

Et si j'essaie un :

select into RW$TEST , LC$VAR4 from select titi.test4 (0, 1 ,RW$TEST , LC$VAR4);

avec les 2 derniers en INOUT, j'ai droit à :
ERREUR : la variable de type RECORD ou ROW ne peut pas faire partie d'une liste INTO à plusieurs éléments

J'ai essayé d'autres syntaxes avec * mais elles produisent une erreur de syntaxe ...

Ya t'il une syntaxe qui convient ?

Hors ligne

#15 30/01/2014 12:08:56

Xav1er
Membre

Re : [] smallint en paramètre in out d'une fonction

Pour le smallint [] en INOUT avec plusieurs paramètres, ça fonctionne en le récupérant avec *, comme pour un champ de type character varying.

Plus que le champ modifié de type ROWTYPE à récupérer, et j'aurai tous les éléments pour voir si mes procédures et fonctions Oracle sont adaptables sous pgsql ...

Hors ligne

#16 23/04/2014 15:17:23

Xav1er
Membre

Re : [] smallint en paramètre in out d'une fonction

Au cas où ça peut aider d'autres personnes, ma problématique était d'écrire une fonction avec plusieurs paramètre inout dont au moins 2 doivent être récupérés avec la syntaxe * comme expliqué par gleu plus haut.
Je n'ai pas réussi à trouver une syntaxe avec un "select" qui fonctionne.
Pour contourner, j'ai créé une table vide avec tous les champs que je voulais (dont 2 de type smallint []).
J'ai créé une variable Var_table MATABLE;
et en faisant VAR_table := ma_fct (var1, Var2, VAR_table);
Ca fonctionnne.
Je ne trouve pas ma solution très propre parce que j'ai créé une table vide juste pour avoir une liste de champs, un peu comme pour définir une structure en C, mais c'est la seule que j'ai trouvée ...

Hors ligne

#17 23/04/2014 21:38:50

gleu
Administrateur

Re : [] smallint en paramètre in out d'une fonction

Pourquoi ne pas avoir créé un type ?

Hors ligne

#18 24/04/2014 09:42:26

Xav1er
Membre

Re : [] smallint en paramètre in out d'une fonction

Et bien ... Parce que je ne savais pas que l'on pouvait faire comme ça.
En effet, ça fonctionne très bien, et là, c'est propre ;-)
Merci !

Hors ligne

#19 24/04/2014 22:09:43

gleu
Administrateur

Re : [] smallint en paramètre in out d'une fonction

Pour infos, le coup de la table fonctionne parce qu'un type est créé du même nom que la table. Mais seul un type de données vous est utile.

Hors ligne

Pied de page des forums