Pourquoi Oracle connecter avec nocycle suit racine cycle

Personne ne sait pourquoi Oracle continue à suivre un chemin au-delà du cycle de la boucle lorsque le cycle se produit en haut de nœud (nœud racine connecté droit de retour au nœud racine)? Plus important encore, comment l'empêcher?

J'ai Oracle 11g Release 2 (11.2) et j'ai été d'explorer des requêtes hiérarchiques. Je vais construire ma question autour de la structure de l'arbre dans la figure 9-1 de la Base de données Oracle SQL Langage de Référence page 9-4

J'ai créé une table structe pour cet arbre à l'aide de la notion de vendeurs et de cusomers:

    create table t
     ( vendor       varchar2(3)
    , customer   varchar2(3)
    );
    insert into t values ( '1'  , '2'  ); 
    insert into t values ( '2'  , '3'  ); 
    insert into t values ( '2'  , '4'  ); 
    insert into t values ( '4'  , '5'  ); 
    insert into t values ( '4'  , '6'  ); 
    insert into t values ( '1'  , '7'  ); 
    insert into t values ( '7'  , '8'  ); 
    insert into t values ( '1'  , '9'  ); 
    insert into t values ( '9'  , '10' ); 
    insert into t values ( '10' , '11' ); 
    insert into t values ( '9'  , '12' ); 
    commit;

La requête de sélection suivante parcourt l'arbre, pas de problèmes:

    select vendor, 
           customer, 
           level, 
           connect_by_isleaf as isleaf, 
           connect_by_iscycle as iscycle, 
           connect_by_root vendor||sys_connect_by_path(customer,' ~ ') as path 
    from t
    connect by nocycle
          vendor=prior customer
    start with vendor='1';

Donner les résultats:

Vendor Cust     Level   Isleaf Iscycle   Path
1        2        1        0        0   1 ~ 2
2        3        2        1        0   1 ~ 2 ~ 3
2        4        2        0        0   1 ~ 2 ~ 4
4        5        3        1        0   1 ~ 2 ~ 4 ~ 5
4        6        3        1        0   1 ~ 2 ~ 4 ~ 6
1        7        1        0        0   1 ~ 7
7        8        2        1        0   1 ~ 7 ~ 8
1        9        1        0        0   1 ~ 9
9        10       2        0        0   1 ~ 9 ~ 10
10       11       3        1        0   1 ~ 9 ~ 10 ~ 11
9        12       2        1        0   1 ~ 9 ~ 12

J'ai ensuite compliquer les choses en ajoutant des cycles de la structure. D'abord un record pour un vendeur qui vend à eux-mêmes...

    --self cycle
    insert into t values ( '4'  , '4'  ); 

et un pour un vendeur dont le client est le fournisseur de leur fournisseur...

    --ancestor cycle
    insert into t values ( '6'  , '2'  ); 

Reexecuting la requête select résultats ci-dessus dans le même résultat que ci-dessus sauf Iscycle est 1 pour la ligne 3 et la ligne 5 (Voies 1 ~ 2 ~ 4 et 1 ~ 2 ~ 4 ~ 6). Notez que la connexion PAR la nomenclature des drapeaux de l'enregistrement parent d'un cycle de ne pas l'enregistrement enfant réellement terminer le cycle. (Donc je sais de 4 et 6 fois le cycle de retour d'un ancêtre, mais je ne sais pas QUI ancêtre.)

Ajout de deux dossiers crée un plus grand vélo dans les branches de l'arbre d'origine:

 --cycle crossing branches of tree
  insert into t values ( '6'  , '9'  ); 
  insert into t values ( '11' , '2'  );  

Reexecuting la requête select de nouveau donne le résultat suivant:

Vendor Customer Level   Isleaf   Iscycle       Path
1        2        1        0        0    1 ~ 2
2        3        2        1        0    1 ~ 2 ~ 3
2        4        2        0        1    1 ~ 2 ~ 4
4        5        3        1        0    1 ~ 2 ~ 4 ~ 5
4        6        3        0        1    1 ~ 2 ~ 4 ~ 6
6        9        4        0        0    1 ~ 2 ~ 4 ~ 6 ~ 9
9       10        5        0        0    1 ~ 2 ~ 4 ~ 6 ~ 9 ~ 10
10      11        6        1        1    1 ~ 2 ~ 4 ~ 6 ~ 9 ~ 10 ~ 11
9       12        5        1        0    1 ~ 2 ~ 4 ~ 6 ~ 9 ~ 12
1        7        1        0        0    1 ~ 7
7        8        2        1        0    1 ~ 7 ~ 8
1        9        1        0        0    1 ~ 9
9       10        2        0        0    1 ~ 9 ~ 10
10      11        3        0        0    1 ~ 9 ~ 10 ~ 11
11       2        4        0        0    1 ~ 9 ~ 10 ~ 11 ~ 2
2        3        5        1        0    1 ~ 9 ~ 10 ~ 11 ~ 2 ~ 3
2        4        5        0        1    1 ~ 9 ~ 10 ~ 11 ~ 2 ~ 4
4        5        6        1        0    1 ~ 9 ~ 10 ~ 11 ~ 2 ~ 4 ~ 5
4        6        6        1        1    1 ~ 9 ~ 10 ~ 11 ~ 2 ~ 4 ~ 6
9       12        2        1        0    1 ~ 9 ~ 12

La sortie continue d'être comme prévu. Tous les cycles sont flaged et la cartographie s'arrête lorsqu'un cycle est détecté.

Maintenant, le problème de l'enfant... ajoutons une auto cycle pour le nœud racine qui est exactement le même que le premier cycle créé ci-dessus avec le nœud 4; juste pour le nœud 1.

    insert into t values ( '1'  , '1'  );

Cette fois, Oracle détecte le cycle au niveau du nœud 1, comme prévu (la première ligne est marqué avec Iscycle mis à 1); TOUTEFOIS, il se prolonge au-delà de ce cycle et construit l'ensemble de la structure de l'arbre deux fois. Les lignes 2 à 21 sont une duplication de lignes 22 à 41 avec le cycle de nœud 1 ajouté sur le devant de la voie.

Vendor Customer  Level Isleaf Iscycle    Path
1        1        1        0    1      1 ~ 1
1        2        2        0    0      1 ~ 1 ~ 2
2        3        3        1    0      1 ~ 1 ~ 2 ~ 3
2        4        3        0    1      1 ~ 1 ~ 2 ~ 4
4        5        4        1    0      1 ~ 1 ~ 2 ~ 4 ~ 5
4        6        4        0    1      1 ~ 1 ~ 2 ~ 4 ~ 6
6        9        5        0    0      1 ~ 1 ~ 2 ~ 4 ~ 6 ~ 9
9       10        6        0    0      1 ~ 1 ~ 2 ~ 4 ~ 6 ~ 9 ~ 10
10      11        7        1    1      1 ~ 1 ~ 2 ~ 4 ~ 6 ~ 9 ~ 10 ~ 11
9       12        6        1    0      1 ~ 1 ~ 2 ~ 4 ~ 6 ~ 9 ~ 12
1        7        2        0    0      1 ~ 1 ~ 7
7        8        3        1    0      1 ~ 1 ~ 7 ~ 8
1        9        2        0    0      1 ~ 1 ~ 9
9       10        3        0    0      1 ~ 1 ~ 9 ~ 10
10      11        4        0    0      1 ~ 1 ~ 9 ~ 10 ~ 11
11       2        5        0    0      1 ~ 1 ~ 9 ~ 10 ~ 11 ~ 2
2        3        6        1    0      1 ~ 1 ~ 9 ~ 10 ~ 11 ~ 2 ~ 3
2        4        6        0    1      1 ~ 1 ~ 9 ~ 10 ~ 11 ~ 2 ~ 4
4        5        7        1    0      1 ~ 1 ~ 9 ~ 10 ~ 11 ~ 2 ~ 4 ~ 5
4        6        7        1    1      1 ~ 1 ~ 9 ~ 10 ~ 11 ~ 2 ~ 4 ~ 6
9       12        3        1    0      1 ~ 1 ~ 9 ~ 12
1        2        1        0    0      1 ~ 2
2        3        2        1    0      1 ~ 2 ~ 3
2        4        2        0    1      1 ~ 2 ~ 4
4        5        3        1    0      1 ~ 2 ~ 4 ~ 5
4        6        3        0    1      1 ~ 2 ~ 4 ~ 6
6        9        4        0    0      1 ~ 2 ~ 4 ~ 6 ~ 9
9       10        5        0    0      1 ~ 2 ~ 4 ~ 6 ~ 9 ~ 10
10      11        6        1    1      1 ~ 2 ~ 4 ~ 6 ~ 9 ~ 10 ~ 11
9       12        5        1    0      1 ~ 2 ~ 4 ~ 6 ~ 9 ~ 12
1        7        1        0    0      1 ~ 7
7        8        2        1    0      1 ~ 7 ~ 8
1        9        1        0    0      1 ~ 9
9       10        2        0    0      1 ~ 9 ~ 10
10      11        3        0    0      1 ~ 9 ~ 10 ~ 11
11       2        4        0    0      1 ~ 9 ~ 10 ~ 11 ~ 2
2        3        5        1    0      1 ~ 9 ~ 10 ~ 11 ~ 2 ~ 3
2        4        5        0    1      1 ~ 9 ~ 10 ~ 11 ~ 2 ~ 4
4        5        6        1    0      1 ~ 9 ~ 10 ~ 11 ~ 2 ~ 4 ~ 5
4        6        6        1    1      1 ~ 9 ~ 10 ~ 11 ~ 2 ~ 4 ~ 6
9       12        2        1    0      1 ~ 9 ~ 12

Pourquoi n'est-ce pas le 1-1 cycle traités de la même façon que le 4-4 cycle? Ce qui me manque?

D'atténuer cette j'ai ajouté une condition supplémentaire sur la connexion PAR la clause exigeant que le client de ne pas être à ‘1’.

    select vendor, 
customer, 
level, 
connect_by_isleaf as isleaf, 
connect_by_iscycle as iscycle, 
connect_by_root vendor||sys_connect_by_path(customer,' ~ ') as path 
from t
connect by nocycle
vendor=prior customer
and customer<>'1' 
start with vendor='1';

Ironiquement, tout cela n'a été de SUPPRIMER le cycle de drapeau à partir de la ligne.

Toute aide serait appréciée.

C'est peut-être parce que 1 est le niveau 1 et le 4 n'est pas. Aussi pourquoi ne pas simplement ajouter des WHERE VENDOR <> CUSTOMER
Je veux être averti lorsque leurs est un cycle, donc je ne veux pas utiliser lorsque le vendeur <> le client. Certains de mes réels arbre structures comportent de 10 à 20 niveaux et des milliers de nœuds. avoir un niveau répliqué provoque des doublons. Selon tous les documents que je peux trouver, il ne devrait pas question que le cycle se produit au niveau un. ...mais il le fait... 🙁
Pourriez-vous vérifier?

OriginalL'auteur Larry May | 2013-09-20