Uit documentatie op CONNECT_BY_ISCYCLE
:
De
CONNECT_BY_ISCYCLE
pseudokolom retourneert1
als de huidige rij een kind heeft dat ook zijn voorouder is
en dat op CYCLE
:
Een rij wordt beschouwd als een cyclus als een van zijn voorouderrijen dezelfde waarden heeft voor de cycluskolommen.
In uw voorbeeld rij 2
heeft wel een kind dat ook zijn voorouder is, maar zijn id
is nog niet teruggestuurd.
Met andere woorden, CONNECT_BY_ISCYCLE
controleert de kinderen (die nog moeten worden geretourneerd), terwijl CYCLE
controleert de huidige rij (die al is geretourneerd).
CONNECT BY
is rijgebaseerd, terwijl recursief CTE
's zijn set-gebaseerd.
Merk op dat de documentatie van Oracle over CYCLE
noemt een "voorouderrij". Over het algemeen is er echter geen concept van een "voorouderrij" in een recursieve CTE
. Het is een op een set gebaseerde bewerking die resultaten kan opleveren die volledig uit de boom zijn. Over het algemeen kunnen het ankergedeelte en het recursieve gedeelte zelfs de verschillende tabellen gebruiken.
Sinds recursieve CTE
's zijn meestal gebruikt om hiërarchiebomen te bouwen, Oracle
besloten om een cycluscontrole toe te voegen. Maar vanwege de set-gebaseerde manier is de recursieve CTE
's werken, is het over het algemeen onmogelijk om te zeggen of de volgende stap een cyclus genereert of niet, omdat zonder een duidelijke definitie van de "voorouderlijke rij" cyclusconditie ook niet kan worden gedefinieerd.
Om de "volgende" stap uit te voeren, moet de hele "huidige" set beschikbaar zijn, maar om elke rij van de huidige set (inclusief de cycluskolom) te genereren, hebben we alleen de resultaten van de "volgende" bewerking nodig.
Het is geen probleem als de huidige set altijd uit één rij bestaat (zoals in CONNECT BY
), maar het is een probleem als de recursieve bewerking op een verzameling als geheel wordt gedefinieerd.
Niet gekeken naar Oracle 11
nog, maar SQL Server
implementeert recursieve CTE
door gewoon een CONNECT BY
. te verbergen achter hen, wat het plaatsen van talrijke beperkingen vereist (die alle in feite alle op sets gebaseerde bewerkingen verbieden).
PostgreSQL
's implementatie daarentegen is echt set-gebaseerd:u kunt elke bewerking uitvoeren met het ankergedeelte in het recursieve gedeelte. Het heeft echter geen middelen om cycli te detecteren, omdat cycli in de eerste plaats niet zijn gedefinieerd.
Zoals eerder vermeld, MySQL
implementeert CTE
niet 's helemaal niet (het implementeert niet HASH JOIN
's of MERGE JOIN
s ook, alleen de geneste lussen, dus wees niet verbaasd).
Ironisch genoeg ontving ik vandaag een brief over dit onderwerp, dat ik in mijn blog zal behandelen.
Bijwerken:
Recursieve CTE
's in SQL Server
zijn niet meer dan CONNECT BY
in vermomming. Zie dit artikel in mijn blog voor schokkende details:
- SQL Server:zijn de recursieve CTE's echt set-based?