Från dokumentation på CONNECT_BY_ISCYCLE
:
CONNECT_BY_ISCYCLE
pseudokolumn returnerar1
om den aktuella raden har ett barn som också är dess förfader
och det på CYCLE
:
En rad anses utgöra en cykel om en av dess förfadersrader har samma värden för cykelkolumnerna.
I ditt exempel, rad 2
har ett barn som också är dess förfader, men dess id
har inte returnerats än.
Med andra ord, CONNECT_BY_ISCYCLE
kontrollerar barnen (som ännu inte har returnerats), medan CYCLE
kontrollerar den aktuella raden (som redan är tillbaka).
CONNECT BY
är radbaserad, medan rekursiv CTE
s är uppsättningsbaserade.
Observera att Oracles dokumentation om CYCLE
nämner en "förfaderrad". Men generellt sett finns det inget koncept för en "förfaderrad" i en rekursiv CTE
. Det är en uppsättningsbaserad operation som kan ge resultat helt utanför trädet. Generellt sett kan ankardelen och den rekursiva delen till och med använda de olika tabellerna.
Sedan rekursiv CTE
s är vanligtvis används för att bygga hierarkiträd, Oracle
beslutade att lägga till en cykelkontroll. Men på grund av det uppsättningsbaserade sättet den rekursiva CTE
s fungerar är det i allmänhet omöjligt att säga om nästa steg genererar en cykel eller inte, för utan en tydlig definition av "förfäderraden" kan cykelvillkoret inte heller definieras.
För att utföra "nästa" steg, måste hela "nuvarande" uppsättningen vara tillgänglig, men för att generera varje rad i den aktuella uppsättningen (som inkluderar cykelkolumnen) behöver vi bara ha resultaten av "nästa" operationen.
Det är inget problem om den aktuella uppsättningen alltid består av en enda rad (som i CONNECT BY
), men det är ett problem om den rekursiva operationen definieras på en uppsättning som helhet.
Tittade inte på Oracle 11
ännu, men SQL Server
implementerar rekursiv CTE
genom att bara dölja en CONNECT BY
bakom dem, vilket kräver att man placerar många restriktioner (som alla i praktiken förbjuder alla set-baserade operationer).
PostgreSQL
s implementering, å andra sidan, är verkligen set-baserad:du kan göra vilken operation som helst med ankardelen i den rekursiva delen. Det har dock inga medel för att upptäcka cykler, eftersom cykler inte definieras i första hand.
Som nämnts tidigare, MySQL
implementerar inte CTE
s alls (den implementerar inte HASH JOIN
s eller MERGE JOIN
s också, bara de kapslade slingorna, så bli inte mycket förvånad).
Ironiskt nog fick jag ett brev idag om just detta ämne, som jag kommer att ta upp i min blogg.
Uppdatering:
Rekursiv CTE
är i SQL Server
är inte fler än CONNECT BY
i förklädnad. Se den här artikeln i min blogg för chockerande detaljer:
- SQL-server:är de rekursiva CTE:erna verkligen uppsättningsbaserade?