Bonjour,
tout d'abord veuillez m'excuser de ne pas avoir mis mon exemple sur APEX, j'ai bien essayé mais j'ai un message d'erreur sur le mot CREATE (?).
Mon problème est le suivant : je voudrais transformer, grâce à une procédure en PL/SQL, une collection d'objets en un curseur qui pointe sur ces objets. A titre d'exemple, j'ai créé un nouveau type ainsi qu'un nouveau type collection (voir pièce jointe create_types.sql) :
1 2 3 4 5 6 7 8
|
CREATE TYPE TEST_TYPE AS OBJECT
(
ATTRIBUT1 VARCHAR2(10),
ATTRIBUT2 VARCHAR2(10)
);
CREATE OR REPLACE TYPE TEST_TYPES AS TABLE OF TEST_TYPE; |
J'ai ensuite un package qui me permet de créer une nouvelle collection et de la transformer (également en pièce jointe) :
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
|
CREATE OR REPLACE PACKAGE BODY TEST_COLLECTION AS
/******************************************************************************
NAME: TEST_COLLECTION
PURPOSE: test de cr&ation de ref cursor sur un e collection d'objets sans utiliser de constructeur d'objet
REVISIONS:
Ver Date Author Description
--------- ---------- --------------- ------------------------------------
1.0 03/07/2007 DENNIL Created this package.
******************************************************************************/
/**
* return a collection of TEST_TYPE
*/
FUNCTION GET_COLLECTION
RETURN ASI.TEST_TYPES
IS
w_collection ASI.TEST_TYPES;
w_object ASI.TEST_TYPE;
BEGIN
w_collection := ASI.TEST_TYPES();
FOR i IN 1..10
LOOP
w_collection.EXTEND;
w_collection(i) := ASI.TEST_TYPE('value'||i, 'value'||(2*i));
END LOOP;
return w_collection;
END GET_COLLECTION;
/**
* try to return a REF cursor on a ASI.TEST_TYPES
*/
FUNCTION GET_COLLECTION_TO_DATASET_1(in_collection ASI.TEST_TYPES)
RETURN DATASET
IS
w_result DATASET;
BEGIN
open w_result for
select ASI.TEST_TYPE(a.attribut1, a.attribut2) from table(in_collection) a;
return w_result;
END GET_COLLECTION_TO_DATASET_1;
END TEST_COLLECTION;
/ |
Pour se donner une idée voici un exemple d'appel (encore en pièce jointe) :
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
|
DECLARE
w_collection ASI.TEST_TYPES;
w_object ASI.TEST_TYPE;
w_dataset ASI.TEST_COLLECTION.DATASET;
i BINARY_INTEGER;
BEGIN
/* collection of ASI.TEST_TYPE */
w_collection := ASI.TEST_COLLECTION.GET_COLLECTION;
dbms_output.put_line('collection count '||w_collection.COUNT);
dbms_output.put_line('-----> loop on collection');
FOR i IN 1..w_collection.COUNT
LOOP
dbms_output.put_line('object['||i||']:'||w_collection(i).ATTRIBUT1);
END LOOP;
/* transformation into DATASET */
w_dataset := ASI.TEST_COLLECTION.GET_COLLECTION_TO_DATASET_1(w_collection);
dbms_output.put_line('-----> loop on dataset objects');
LOOP
FETCH w_dataset INTO w_object;
EXIT WHEN w_dataset%NOTFOUND;
dbms_output.put_line(w_object.ATTRIBUT1);
END LOOP;
COMMIT;
END; |
Le problème est le suivant : je osuhaiterais, si c'est possible, rendre cette instruction générique :
select ASI.TEST_TYPE(a.attribut1, a.attribut2) from table(in_collection) a;
En effet, ma procédure ne fonctionne qu'avec le type ASI.TEST_TYPE, et je voudrais l'écrire pour qu'elle fonctionne avec tout objet passé en paramètre (y compris des objets complexes ayant comme membres d'autres objets, dont on ne pourra pas facilement appeler le constructeur).
N'hésitez pas à demander des précisions si quelque chose n'est pas clair!
Merci d'avance!
Partager