Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Wykrywanie cykli z rekurencyjnym faktoringiem podzapytań

Z dokumentacji dotyczącej CONNECT_BY_ISCYCLE :

CONNECT_BY_ISCYCLE pseudokolumna zwraca 1 jeśli bieżący wiersz ma dziecko, które jest również jego przodkiem

i to w CYCLE :

Uznaje się, że wiersz tworzy cykl, jeśli jeden z jego wierszy przodków ma te same wartości dla kolumn cyklu.

W twoim przykładzie wiersz 2 ma dziecko, które jest również jego przodkiem, ale jego id nie został jeszcze zwrócony.

Innymi słowy, CONNECT_BY_ISCYCLE sprawdza dzieci (które jeszcze nie zostały zwrócone), podczas gdy CYCLE sprawdza bieżący wiersz (który już został zwrócony).

CONNECT BY jest oparty na wierszach, podczas gdy rekurencyjne CTE są oparte na zestawach.

Zwróć uwagę, że dokumentacja Oracle dotycząca CYCLE wspomina o „rzędu przodków”. Jednak ogólnie rzecz biorąc, nie istnieje pojęcie „rzędu przodka” w rekurencyjnym CTE . Jest to operacja oparta na zbiorach, która może przynieść wyniki całkowicie poza drzewem. Ogólnie rzecz biorąc, część zakotwiczona i część rekurencyjna mogą nawet używać różnych tabel.

Od rekursywnego CTEzazwyczaj używany do budowania drzew hierarchicznych, Oracle postanowił dodać kontrolę cyklu. Ale ze względu na sposób oparty na zbiorach rekurencyjne CTE , generalnie nie można stwierdzić, czy następny krok wygeneruje cykl, czy nie, ponieważ bez jasnej definicji warunku cyklu „rzędu przodka” również nie można zdefiniować.

Aby wykonać „następny” krok, cały „bieżący” zestaw musi być dostępny, ale aby wygenerować każdy wiersz bieżącego zestawu (w tym kolumnę cyklu) wystarczy mieć wyniki operacji „następny”.

Nie jest problemem, jeśli bieżący zestaw zawsze składa się z jednego wiersza (jak w CONNECT BY ), ale jest to problem, jeśli operacja rekurencyjna jest zdefiniowana na zbiorze jako całości.

Nie zajrzałem do Oracle 11 jeszcze, ale SQL Server implementuje rekurencyjne CTE wystarczy ukryć CONNECT BY za nimi, co wymaga nałożenia licznych ograniczeń (z których wszystkie skutecznie zabraniają wszelkich operacji opartych na zestawach).

PostgreSQL Z drugiej strony implementacja 's jest naprawdę oparta na zbiorach:możesz wykonać dowolną operację z częścią zakotwiczoną w części rekurencyjnej. Nie ma jednak żadnych środków do wykrywania cykli, ponieważ cykle nie są zdefiniowane w pierwszej kolejności.

Jak wspomniano wcześniej, MySQL nie implementuje CTE w ogóle (nie implementuje HASH JOIN 's lub MERGE JOIN s również tylko zagnieżdżone pętle, więc nie zdziw się zbytnio).

Jak na ironię, otrzymałem dzisiaj list na ten właśnie temat, który opiszę na moim blogu.

Aktualizacja:

Rekurencyjne CTE jest w SQL Server są nie większe niż CONNECT BY w przebraniu. Zobacz ten artykuł na moim blogu, aby uzyskać szokujące szczegóły:

  • SQL Server:czy rekursywne CTE jest naprawdę oparte na zestawie?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Odwracanie ciągu znaków w SQL i PL/SQL Przykład

  2. Jak wyeliminować godziny wolne od pracy w Oracle

  3. Cloud Native i DevSecOps na dużą skalę dzięki Capgemini Agile Innovation Platform i Oracle Cloud

  4. NAME_IN wbudowana w Oracle D2k Forms

  5. Jak przekazać List z java do procedury Oracle?