Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
#1 06/07/2011 09:52:47
- yo_haha
- Membre
Erreur lors de l'appel d'une fonction retournant SET OF RECORD
Bonjour,
J'ai une fonction retournant SET OF RECORD comme valeur de retour. Lorsque j'appelle cette fonction : SELECT * FROM ma_fonction(), j'ai une erreur : ERREUR: indice du tableau en dehors de l'échelle. Dans la fonction j'utilise un tableau à deux dimensions de type VARCHAR[][] que j'utilise sans initialisation préalable parce que je ne connais pas le nombre de colonnes ni de lignes (ces nombres sont les résultats d'une requête SQL).
Est-ce que l'erreur vient de là ?
Cordialement.
Hors ligne
#2 06/07/2011 10:42:27
- gleu
- Administrateur
Re : Erreur lors de l'appel d'une fonction retournant SET OF RECORD
Possible. Difficile à dire sans voir le code de la fonction.
Guillaume.
Hors ligne
#3 06/07/2011 11:00:07
- yo_haha
- Membre
Re : Erreur lors de l'appel d'une fonction retournant SET OF RECORD
La fonction :
/*La fonction retourne un tableau croisé de tous les sondages dans la première ligne et toutes
les couches litho dans la première colonne. Dans les autres cellules elle met la profondeur de
la couche litho de la même colonne dans le sondage de la même ligne */
DROP FUNCTION litho_sondage();
CREATE OR REPLACE FUNCTION litho_sondage() RETURNS SETOF text AS $$
DECLARE
i INTEGER := 2;
j INTEGER := 2;
tailleSond INTEGER := 0;
tailleLitho INTEGER := 0;
trouve INTEGER := 0;
found1 INTEGER := 0;
found2 INTEGER := 0;
ligne RECORD;
tab RECORD;
tableau VARCHAR[];
elem VARCHAR;
numsond CURSOR FOR SELECT num_sondage FROM sondage;
nomlitho CURSOR FOR SELECT nom_litho FROM lithostratigraphie;
resultat CURSOR FOR SELECT num_sondage, code_sondage, num_litho, nom_litho, toit_form_prof
FROM sondage, litho, litho_sondage
WHERE num_sondage=sondage AND num_litho=litho;
BEGIN
tableau[1][1] := 'Litho/Sondage';
--Remplissage de la première colonne par les nom des couches litho
OPEN nomlitho;
LOOP
FETCH nomlitho INTO ligne;
EXIT WHEN NOT FOUND;
tableau[i][1] = ligne.nom_litho;
i := i+1;
END LOOP;
CLOSE nomlitho;
--Remplissage de la première ligne par les numéros des sondages
i := 2;
OPEN numsond;
LOOP
FETCH numsond INTO ligne;
EXIT WHEN NOT FOUND;
tableau[1][i] = ligne.code_sond;
i := i+1;
END LOOP;
CLOSE numsond;
--Remplissage des autres cellules par les profondeurs
i := 2;
OPEN resultat;
LOOP
FETCH resultat INTO ligne;
EXIT WHEN NOT FOUND;
--Recherche du sondage correspondant à la ligne résultat de la requête SQL
LOOP
IF tableau[i][1] = ligne.num_sondage THEN
FOUND1 := 1;
END IF;
EXIT WHEN FOUND1 = 1;
i := i+1;
END LOOP;
FOUND1 := 0;
--Recherche de la couche litho correspondant à la ligne résultat de la requête SQL
LOOP
IF tableau[1][j] = ligne.nom_litho THEN
FOUND2 := 1;
END IF;
EXIT WHEN FOUND2 = 1;
j := j+1;
END LOOP;
FOUND2 := 0;
--Remplissage de la cellule (i,j)
tableau[i][j] := ligne.toit_form_prof;
i := 2;
j := 2;
END LOOP;
CLOSE resultat;
j := 1;
--Elimination des lignes dont les cellules sont nulles : Elimination des couches litho n'apparaissant dans aucun sondage
FOR tab IN SELECT unnest(tableau) LOOP
--La première ligne du tableau contient les noms des sondages, on passe aux suivantes
IF j = 1 THEN
j := j+1;
CONTINUE;
END IF;
i := 1;
FOR elem IN SELECT unnest(tab) LOOP
--La première colonne du tableau contient les noms des couches litho, on passe aux suivantes
IF i = 1 THEN
i := i+1;
CONTINUE;
ELSIF elem IS NOT NULL THEN
trouve := 1;
END IF;
--Si la ligne contient au moins une case non nulle, elle est gardée et on passe à la ligne suivante
IF trouve = 1 THEN
RETURN NEXT tab;
EXIT;
END IF;
END LOOP;
END LOOP;
RETURN;
END;
$$ LANGUAGE 'plpgsql';
J'exécute la fonction de cette façon :
SELECT * FROM litho_sondage()
Hors ligne
#4 06/07/2011 22:43:56
- gleu
- Administrateur
Re : Erreur lors de l'appel d'une fonction retournant SET OF RECORD
Et l'erreur survient sur quelle ligne de cette procédure ?
Guillaume.
Hors ligne
#5 07/07/2011 09:31:56
- yo_haha
- Membre
Re : Erreur lors de l'appel d'une fonction retournant SET OF RECORD
L'erreur apparaît lorssque j'exécute la requête suivante :
SELECT * FROM litho_sondage()
Voici le message d'erreur :
RREUR: indice du tableau en dehors de l'échelle
CONTEXT: PL/pgSQL function "litho_sondage" line 43 at affectation
********** Erreur **********
ERREUR: indice du tableau en dehors de l'échelle
État SQL :2202E
Contexte : PL/pgSQL function "litho_sondage" line 43 at affectation
Dernière modification par yo_haha (07/07/2011 09:47:22)
Hors ligne
#6 07/07/2011 11:20:53
- daamien
- damien clochard
Re : Erreur lors de l'appel d'une fonction retournant SET OF RECORD
L'erreur se trouve au niveau de la matrice tableau[i][j]. Vous ne pouvez pas faire grandir dynamiquement un tableau multi-dimensionnel. Ce qui fonctionne pour un tableau simple ne marche pas si vous ajouter un deuxième axe.
Il existe des solutions de contournement :
* vous pouvez tenter de fixer la taille du tableau à l'avance
* faire un pseudo-tableau 2D dans un tableau 1D
Le lien ci-dessous est assez complet. c'est en espagnol mais le code est universel
damien clochard
http://dalibo.org | http://dalibo.com
Hors ligne
#7 07/07/2011 12:54:54
- yo_haha
- Membre
Re : Erreur lors de l'appel d'une fonction retournant SET OF RECORD
Est-ce possible de remplecer tableau VARCHAR[][] par
taille_litho INTEGER;
SELECT INTO taille_litho count(num_litho) FROM lithostratigraphie;
taille_sond INTEGER;
SELECT INTO taille_sond count(num_sond) FROM sondage;
tableau VARCHAR[taille_litho][taille_sond];
elem VARCHAR;
Hors ligne
#8 07/07/2011 22:12:48
- gleu
- Administrateur
Re : Erreur lors de l'appel d'une fonction retournant SET OF RECORD
Non, ce n'est pas possible. Toutes les déclarations se font dans la partie DECLARE en tout début. De plus, il n'est pas possible d'utiliser des variables comme indice de tableau dans la partie DECLARE.
Guillaume.
Hors ligne
#9 08/07/2011 09:16:03
- yo_haha
- Membre
Re : Erreur lors de l'appel d'une fonction retournant SET OF RECORD
Donc ce n'est nonplus possible de passer la taille du tableau en argument de la fonction ?
Hors ligne
#10 08/07/2011 09:32:35
- gleu
- Administrateur
Re : Erreur lors de l'appel d'une fonction retournant SET OF RECORD
Exact.
Guillaume.
Hors ligne