À partir de la documentation sur CONNECT_BY_ISCYCLE
:
Le
CONNECT_BY_ISCYCLE
la pseudo-colonne renvoie1
si la ligne courante a un enfant qui est aussi son ancêtre
et cela sur CYCLE
:
Une ligne est considérée comme formant un cycle si l'une de ses lignes ancêtre a les mêmes valeurs pour les colonnes du cycle.
Dans votre exemple, ligne 2
a un enfant qui est aussi son ancêtre, mais son id
n'a pas encore été retourné.
En d'autres termes, CONNECT_BY_ISCYCLE
vérifie les enfants (qui n'ont pas encore été retournés), tandis que CYCLE
vérifie la ligne actuelle (qui est déjà retourné).
CONNECT BY
est basé sur les lignes, tandis que CTE
récursif sont basés sur des ensembles.
Notez que la documentation d'Oracle sur CYCLE
mentionne une « ligne ancêtre ». Cependant, de manière générale, il n'y a pas de concept de "ligne ancêtre" dans un CTE
récursif . C'est une opération basée sur un ensemble qui peut donner des résultats complètement hors de l'arbre. De manière générale, la partie ancre et la partie récursive peuvent même utiliser les différentes tables.
Depuis CTE
récursif sont habituellement utilisé pour construire des arborescences hiérarchiques, Oracle
a décidé d'ajouter une vérification de cycle. Mais en raison de la manière basée sur les ensembles, le CTE
récursif , il est généralement impossible de dire si l'étape suivante générera un cycle ou non, car sans une définition claire de la condition de cycle "ligne ancêtre", il est impossible de définir non plus.
Pour effectuer l'étape "suivante", tout l'ensemble "courant" doit être disponible, mais pour générer chaque ligne de l'ensemble courant (qui inclut la colonne de cycle), nous avons juste besoin d'avoir les résultats de l'opération "suivante".
Ce n'est pas un problème si l'ensemble actuel se compose toujours d'une seule ligne (comme dans CONNECT BY
), mais c'est un problème si l'opération récursive est définie sur un ensemble dans son ensemble.
Je n'ai pas regardé Oracle 11
pour le moment, mais SQL Server
implémente CTE
récursif en masquant simplement un CONNECT BY
derrière eux, ce qui nécessite de placer de nombreuses restrictions (qui interdisent toutes de fait toutes les opérations basées sur les ensembles).
PostgreSQL
L'implémentation de , en revanche, est véritablement basée sur les ensembles :vous pouvez effectuer n'importe quelle opération avec la partie d'ancrage dans la partie récursive. Cependant, il n'a aucun moyen de détecter les cycles, car les cycles ne sont pas définis en premier lieu.
Comme mentionné précédemment, MySQL
n'implémente pas CTE
's du tout (il n'implémente pas HASH JOIN
ou MERGE JOIN
s aussi, seulement les boucles imbriquées, alors ne soyez pas trop surpris).
Ironiquement, j'ai reçu une lettre aujourd'hui sur ce sujet précis, que je couvrirai dans mon blog.
Mise à jour :
CTE
récursif est dans SQL Server
ne sont pas plus que CONNECT BY
déguisé. Voir cet article sur mon blog pour des détails choquants :
- SQL Server :les CTE récursifs sont-ils vraiment basés sur des ensembles ?