Da documentação em
CONNECT_BY_ISCYCLE
:
OCONNECT_BY_ISCYCLE
pseudocoluna retorna1
se a linha atual tiver um filho que também seja seu ancestral
e que em
CYCLE
:
Uma linha é considerada um ciclo se uma de suas linhas ancestrais tiver os mesmos valores para as colunas do ciclo.
No seu exemplo, linha
2
tem um filho que também é seu ancestral, mas seu id
ainda não foi devolvido. Em outras palavras,
CONNECT_BY_ISCYCLE
verifica os filhos (que ainda não foram retornados), enquanto CYCLE
verifica a linha atual (que já foi devolvido). CONNECT BY
é baseado em linhas, enquanto o CTE
recursivo s são baseados em conjuntos. Observe que a documentação da Oracle sobre
CYCLE
menciona uma "linha ancestral". No entanto, de um modo geral, não há conceito de uma "linha ancestral" em um CTE
recursivo . É uma operação baseada em conjunto que pode produzir resultados completamente fora da árvore. De um modo geral, a parte âncora e a parte recursiva podem até usar as diferentes tabelas. Desde o
CTE
recursivo s são geralmente usado para construir árvores de hierarquia, Oracle
decidiu adicionar uma verificação de ciclo. Mas devido à forma baseada em conjuntos, o CTE
recursivo 's operam, geralmente é impossível dizer se a próxima etapa gerará um ciclo ou não, porque sem uma definição clara da condição de ciclo "linha ancestral" também não pode ser definida. Para realizar o passo "próximo", todo o conjunto "atual" precisa estar disponível, mas para gerar cada linha do conjunto atual (que inclui a coluna do ciclo) precisamos apenas ter os resultados da operação "próximo".
Não é um problema se o conjunto atual sempre consistir em uma única linha (como em
CONNECT BY
), mas é um problema se a operação recursiva for definida em um conjunto como um todo. Não olhou para o
Oracle 11
ainda, mas SQL Server
implementa CTE
recursivo 's apenas ocultando um CONNECT BY
atrás deles, o que exige a colocação de inúmeras restrições (todas as quais efetivamente proíbem todas as operações baseadas em conjuntos). PostgreSQL
A implementação de 's, por outro lado, é realmente baseada em conjuntos:você pode fazer qualquer operação com a parte âncora na parte recursiva. Ele não tem nenhum meio para detectar ciclos, no entanto, porque os ciclos não são definidos em primeiro lugar. Como mencionado anteriormente,
MySQL
não implementa CTE
's (não implementa HASH JOIN
's ou MERGE JOIN
s também, apenas os loops aninhados, então não se surpreenda muito). Ironicamente, recebi hoje uma carta sobre esse mesmo assunto, que abordarei em meu blog.
Atualização:
CTE
recursivo 's em SQL Server
não são maiores que CONNECT BY
disfarçado. Veja este artigo no meu blog para detalhes chocantes:- SQL Server:os CTEs recursivos são realmente baseados em conjuntos?