Précédent   Forum des professionnels en informatique > Bases de données > Oracle > PL/SQL
PL/SQL Forum d'entraide sur le PL/SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 29/07/2011, 16h33   #1
Invité régulier
 
Homme
Développeur informatique
Inscription : juin 2011
Messages : 10
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2011
Messages : 10
Points : 5
Points : 5
Par défaut FUNCTION PIPELINED RETURN SET OF ROWS

Bonjour,
Je souhait écrire une fonction qui me retourne une table d'un type que j'ai défini moi même.
j'ai cette erreur
Citation:
PLS-00302: le composant 'ID_GR' doit être déclaré.
PLS-00328: expression du mauvais type
ou ID_GR est la première colonne de mon type 'data_groupe'

Code :
1
2
3
4
5
6
7
8
9
CREATE TYPE data_groupe AS OBJECT
(
    id_gr NUMBER,
    lib_gr VARCHAR2(50),
    id_descri NUMBER,
    lib_descri VARCHAR2(50),
    id_br NUMBER,
    seuil_br DOUBLE PRECISION
    );
Code :
CREATE TYPE table_data_groupe AS TABLE OF data_groupe;
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
CREATE OR REPLACE FUNCTION get_data_groupe (id_prod IN NUMBER)
   RETURN table_data_groupe
   PIPELINED
IS
 
   out_rec    table_data_groupe
                 := table_data_groupe (NULL,
                                       NULL,
                                       NULL,
                                       NULL,
                                       NULL,
                                       NULL);
    CURSOR l_cursor IS
        SELECT g.id AS id_gr,
               g.libelle AS lib_gr,
               d.id AS id_descri,
               d.nom AS lib_descri,
               b.id AS id_br,
               b.seuil_bareme AS seuil_br
          FROM pnp_fournisseur f,
               pnp_entrepot e,
               pnp_produit p,
               pnp_composition_groupe cg,
               pnp_groupe g,
               pnp_groupe_descripteur gd,
               pnp_descripteur d,
               pnp_descripteur_bareme db,
               pnp_bareme b
         WHERE     p.id = id_prod
               AND f.id = cg.id_fournisseur
               AND e.id = cg.id_entrepot
               AND p.id = cg.id_produit
               AND cg.id_groupe = g.id
               AND g.id = gd.id_groupe
               AND gd.id_descripteur = d.id
               AND d.id = db.id_descripteur
               AND db.id_bareme = b.id;                                   
BEGIN
   OPEN l_cursor;        
      LOOP
        FETCH l_cursor INTO
 
            out_rec.id_gr, 
            out_rec.lib_gr,
            out_rec.id_descri,
            out_rec.lib_descri,
            out_rec.id_br,
            out_rec.seuil_br;       
        EXIT WHEN l_cursor%NOTFOUND;
        PIPE ROW(out_rec);
    END LOOP;
 
CLOSE l_cursor;
RETURN;
END;
cpu64 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/08/2011, 11h30   #2
Membre confirmé
 
Homme Grégoire MARTIN
Ingénieur développement logiciels
Inscription : janvier 2011
Messages : 128
Détails du profil
Informations personnelles :
Nom : Homme Grégoire MARTIN
Âge : 32
Localisation : France, Hauts de Seine (Île de France)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : Finance

Informations forums :
Inscription : janvier 2011
Messages : 128
Points : 225
Points : 225
Bonjour,

Voici un exemple :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
DROP FUNCTION func_pipelined_test;
DROP TYPE array_record_test;
DROP TYPE record_test;
 
CREATE TYPE record_test AS OBJECT ( ID_REC NUMBER
                                   ,VALUE_REC VARCHAR2(50)
                                  );
 
CREATE TYPE array_record_test AS TABLE OF record_test;
 
CREATE OR REPLACE FUNCTION func_pipelined_test 
RETURN array_record_test PIPELINED
IS
 
out_record_test array_record_test := array_record_test() ;
 
CURSOR cur_test
IS
       SELECT 1 AS ID_REC,'value 1' AS VALUE_REC FROM DUAL UNION ALL
       SELECT 2,'value 2' FROM DUAL UNION ALL
       SELECT 3,'value 3' FROM DUAL
;
 
TYPE array_test IS TABLE OF cur_test%ROWTYPE INDEX BY BINARY_INTEGER;
 
in_record_test array_test;
 
BEGIN
 
  OPEN cur_test;
  LOOP
     FETCH cur_test BULK COLLECT INTO in_record_test;              
       FOR i IN 1 .. in_record_test.COUNT
       LOOP                                    
           out_record_test.EXTEND;                        
           out_record_test(out_record_test.last) := record_test(in_record_test(i).ID_REC
                                                                ,in_record_test(i).VALUE_REC);             
           PIPE ROW(out_record_test(out_record_test.last));
       END LOOP;       
     EXIT WHEN cur_test%NOTFOUND;
  END LOOP;
  CLOSE cur_test;
 
RETURN;
EXCEPTION
       WHEN OTHERS THEN
       IF cur_test%ISOPEN THEN
          CLOSE cur_test;
       END IF;       
       RETURN;
END;
 
 
SELECT * FROM TABLE(func_pipelined_test);
ORA-007 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/08/2011, 11h34   #3
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 437
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 437
Points : 4 173
Points : 4 173
ligne 7, c'est le record qu'il faudrait initialiser.

Sinon, préfère les FOR LOOP, plus simples à coder/debuguer.
J'utilise les fonctions pipelined comme ceci :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
CREATE OR REPLACE FUNCTION get_data_groupe (id_prod IN NUMBER)
   RETURN table_data_groupe
   PIPELINED
IS
    CURSOR l_cursor IS
        SELECT g.ID AS id_gr, g.libelle AS lib_gr,
        				d.ID AS id_descri, d.nom AS lib_descri, 
               b.ID AS id_br, b.seuil_bareme AS seuil_br
        FROM pnp_fournisseur f,
               pnp_entrepot e,
               pnp_produit p,
               pnp_composition_groupe cg,
               pnp_groupe g,
               pnp_groupe_descripteur gd,
               pnp_descripteur d,
               pnp_descripteur_bareme db,
               pnp_bareme b
         WHERE     p.ID = id_prod
               AND f.ID = cg.id_fournisseur
               AND e.ID = cg.id_entrepot
               AND p.ID = cg.id_produit
               AND cg.id_groupe = g.ID
               AND g.ID = gd.id_groupe
               AND gd.id_descripteur = d.ID
               AND d.ID = db.id_descripteur
               AND db.id_bareme = b.ID;                                   
BEGIN
   FOR r IN l_cursor;        
   LOOP
      PIPE ROW( DATA_GROUPE(r.id_gr, r.lib_gr, r.id_descri, r.lib_descri, r.id_br, r.seuil_br);
   END LOOP;
 	RETURN;
END;
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/08/2011, 11h03   #4
Invité régulier
 
Homme
Développeur informatique
Inscription : juin 2011
Messages : 10
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2011
Messages : 10
Points : 5
Points : 5
Bonjour,
Merci pour vos réponses. J'ai opté pour la solution de McM.
cpu64 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 13h26.


 
 
 
 
Partenaires

Hébergement Web