2010-12-02 24 views
1

J'ai une table qui contient des données représentant des structures hiérarchiques. Le moyen le plus simple d'extraire des données de cette table pour un seul "objet" est une requête récursive. La même table stocke également les "variables membres" associées à "l'objet". Je pensais que ce serait agréable de voir la structure de l'objet ainsi que les variables membres associés dans une seule requête, j'ai donc essayé quelque chose comme:Mélange des requêtes récursives et des expressions de curseur

cursor object_explorer is 
      select (level*2) lvl, ob.object_id, lpad(ot1.object_type_name, 2*level + length(ot1.object_type_name), '.') ob_typ_nam 
       from obj_tab ob, obj_type ot1 
        , cursor (select lpad(mv.member_var_name, level + length(mv.member_var_name), ' ') var_nam, /*other stuff*/ 
          from obj_type ot2, object_memberVar_value omv, member_variable mv 
           where mv.member_variable_id = omv.member_variable_id 
           and ot2.object_type_id = omv.object_type_id 
           and omv.object_id = ob.object_id) 
       where ot1.object_type_id = ob.object_type_id 
       and /*other filtering conditions unrelated to problem at hand*/ 
       start with ob.objecT_id = '1234567980ABC' 
       connect by nocycle ob.parent_object = prior ob.object_id; 

... et Oracle me dit « l'expression du curseur non autorisé ». Si je le fais en tant que deux curseurs distincts (bouclage à travers les résultats d'un, puis en utilisant l'autre curseur basé sur ces résultats), tout fonctionne bien, donc je n'ai pas besoin une solution de curseur unique. Je voulais juste savoir pourquoi je ne peux pas combiner ces deux requêtes en utilisant des expressions de curseur - ou peut je les combine et je l'ai juste manqué en quelque sorte?

(version Oracle est 10g)

+0

Je ne pense pas que vous pouvez utiliser l'expression Cursor dans la clause from .. Je ne comprends pas non plus exactement ce que vous essayez de faire ici. Pouvez-vous donner un exemple de la production que vous espérez? – Craig

+0

@Craig: Vous avez raison. J'ai dû déplacer l'expression du curseur vers la clause SELECT. – FrustratedWithFormsDesigner

Répondre

2

Je ne pense pas que vous devez utiliser le mot-clé curseur. Comme l'explication des états ora-22902, CURSOR() est applicable uniquement dans la projection d'une instruction SELECT.

Nous pouvons utiliser des vues en ligne dans notre clause FROM. Dans votre cas, cela ressemblerait à ceci:

.... 
from obj_tab ob, obj_type ot1 
    , (select omv.object_id 
       , lpad(mv.member_var_name, level + length(mv.member_var_name), ' ') var_nam 
       , /*other stuff*/ 
     from obj_type ot2, object_memberVar_value omv, member_variable mv 
     where mv.member_variable_id = omv.member_variable_id 
     and ot2.object_type_id = omv.object_type_id 
     ) iv 
where iv.object_id = ob.object_id 
and /*filtering conditions unrelated to problem at hand*/ 
.... 

Votre clause WHERE est pas assez bon, parce que vous avez besoin de quelque chose qui rejoint le point de vue en ligne à obj_type et/ou OBJ_TAB. C'est pourquoi j'ai déplacé omv.object_id dans la projection de la sous-requête: pour donner un crochet à la clause WHERE de la requête externe.

+0

vous avez raison, j'étais trop rapide pour se débarrasser de l'ordure supplémentaire, je me suis débarrassé des conditions de jointure. Je le corrige ... – FrustratedWithFormsDesigner

+0

Yup, pour une raison quelconque j'ai eu l'expression du curseur dans la mauvaise partie de la requête. J'ai relu ta réponse, jeté un autre coup d'œil, fait un visage-palme, et l'ai réparé. Fonctionne bien maintenant. – FrustratedWithFormsDesigner