sql >> Databáze >  >> RDS >> Oracle

Detekce cyklů s rekurzivním faktoringem poddotazů

Z dokumentace na CONNECT_BY_ISCYCLE :

CONNECT_BY_ISCYCLE pseudosloupec vrací 1 pokud má aktuální řádek potomka, který je zároveň jeho předkem

a to na CYCLE :

Řádek se považuje za cyklus, pokud jeden z jeho předchůdců má stejné hodnoty pro sloupce cyklu.

Ve vašem příkladu řádek 2 má potomka, který je také jeho předkem, ale jeho id ještě nebyl vrácen.

Jinými slovy, CONNECT_BY_ISCYCLE kontroluje děti (které ještě mají být vráceny), zatímco CYCLE zkontroluje aktuální řádek (který je již vrácen).

CONNECT BY je založen na řádcích, zatímco rekurzivní CTE 's jsou založeny na množinách.

Všimněte si, že dokumentace Oracle o CYCLE zmiňuje „řadu předků“. Nicméně obecně řečeno, v rekurzivním CTE neexistuje žádný koncept "řádku předků" . Je to operace založená na množině, která může přinést výsledky zcela mimo strom. Obecně řečeno, kotevní část a rekurzivní část mohou dokonce používat různé tabulky.

Od rekurzivního CTE 's jsou obvykle používá se k vytváření hierarchických stromů, Oracle rozhodl přidat kontrolu cyklu. Ale kvůli způsobu založenému na množinách rekurzivní CTE 's funguje, je obecně nemožné říct, zda další krok vygeneruje cyklus nebo ne, protože bez jasné definice "řádku předka" nelze definovat ani podmínku cyklu.

K provedení „dalšího“ kroku musí být k dispozici celá „aktuální“ sada, ale pro vygenerování každého řádku aktuální sady (který zahrnuje sloupec cyklu) potřebujeme mít pouze výsledky operace „další“.

Není problém, pokud se aktuální sada vždy skládá z jednoho řádku (jako v CONNECT BY ), ale je to problém, pokud je rekurzivní operace definována na množině jako celku.

Nezkoumal jsem Oracle 11 zatím, ale SQL Server implementuje rekurzivní CTE 's pouhým skrytím CONNECT BY za nimi, což vyžaduje zavedení četných omezení (z nichž všechna fakticky zakazují všechny operace založené na množinách).

PostgreSQL Implementace 's je na druhé straně skutečně založená na množinách:s kotvící částí v rekurzivní části můžete provádět jakoukoli operaci. Nemá však žádné prostředky k detekci cyklů, protože cykly nejsou na prvním místě definovány.

Jak již bylo zmíněno, MySQL neimplementuje CTE 's vůbec (neimplementuje HASH JOIN 's nebo MERGE JOIN s také pouze vnořené smyčky, takže se moc nedivte).

Je ironií, že jsem dnes dostal dopis právě na toto téma, kterému se budu věnovat na svém blogu.

Aktualizace:

Rekurzivní CTE 's v SQL Server nejsou více než CONNECT BY v přestrojení. Šokující podrobnosti najdete v tomto článku na mém blogu:

  • SQL Server:jsou rekurzivní CTE skutečně založeny na sadě?


  1. Jak uniknout vyhrazenému slovu v Oracle?

  2. pomocí (-) pomlčky v názvu tabulky mysql

  3. Připojení k Db zanikne po>4<24 v režimu spánku jpa při spuštění na jaře

  4. Jak změnit tabulku na serveru SQL Server pomocí příkazu Alter - SQL Server / Výukový program T-SQL, část 35