Bonjour,
Je suis actuellement en train d'évaluer les possibilités de programmation objet avec oracle et le pl/sql et il y a un petit truc qui me chagrine... Je ne trouve pas de moyen natif (sans passer par des requêtes "from dual") pour traiter différemment les types enfants du type parent.
Voici un exemple de hiérarchie d'objets avec une table les contenant :
1 2 3 4 5 6 7 8 9 10 11
| CREATE TYPE person_typ AS OBJECT (
idno NUMBER,
name VARCHAR2(30),
phone VARCHAR2(20))
NOT FINAL;
CREATE TYPE person_enfant under person_typ (
prenom VARChAR2(20))
not final;
CREATE TABLE person_obj_table of person_typ |
Avec l'aide d'un curseur défini sur la requête suivante :
select ref(p) as refs from person_obj_table p
J'arrive à "charger" mes objets stockés dans une instance du type parent grâce au package "UTL_REF" et sa méthode "Lock_Object". Seulement, si je suis bien capable de déterminer s'il s'agit d'un type person_typ ou person_enfant via la fonction "IS OF (Type_name)" ou en passant par un "anydata.convertObjet().getTypeName", le compilateur PL/SQL ne me laisse pas utiliser les attributs (ou méthodes) de l'instance enfant chargée (normal vu que c'est connu uniquement en runtime...)
La fonction "treat" ne fonctionnant apparemment qu'en sql (pas en pl) y a-t-il un autre moyen de "transtyper" l'instance dans le bon type pour le compilateur?
Actuellement, la seule solution que j'ai pu trouver et de faire le contrôle du type avant de charger la référence afin de pouvoir choisir l'objet de destination (soit du type parent, soit du type enfant) comme ceci :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| DECLARE
Cursor curSelectRef is
select ref(p) as refs, value(p) as obj FROM person_obj_table p;
parent person_typ;
enfant person_typ;
BEGIN
FOR rec in curSelectRef LOOP -- Curseur précédemment présenté
if rec.obj is of(person_enfant) Then
utl_ref.lock_Object(rec.refs, enfant);
enfant.prenom:= 'prenom';
parent:= enfant;
Else
utl_ref.lock_Object(rec.refs, parent);
End IF;
-- Traitement commun parent+enfant
-- Sauve les modifs dans la table
utl_ref.update_object(rec.refs, parent);
END LOOP; |
Le problème c'est que je dois alors déclarer deux objets (un par type) et je ne trouve pas ça terrible... Il serait également possible de faire le traitement dans des procédures/fonctions que je pourrais surcharger pour chaque sous-type... mais ça me semble bien compliqué pour un traitement aussi simple... Y a-t-il un moyen plus "générique" de le faire et si possible en "full PL/SQL" ?
J'ai parcouru beaucoup de documentations, mais la plupart ne présentent que la partie sql des traitements...avec parfois une annotation comme quoi telle ou telle fonction n'est pas supportée en PL...
(ps : Je test ça sur une 10g, mais si il y a des changements notables sur la 11, je suis preneur de l'info même si elle ne me servira pas dans un premier temps =)
Partager