Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Phát hiện chu kỳ với tính toán truy vấn con đệ quy

Từ tài liệu trên CONNECT_BY_ISCYCLE :

CONNECT_BY_ISCYCLE cột giả trả về 1 nếu hàng hiện tại có một con cũng là tổ tiên của nó

và điều đó trên CYCLE :

Một hàng được coi là tạo thành chu kỳ nếu một trong các hàng tổ tiên của nó có cùng giá trị cho các cột chu kỳ.

Trong ví dụ của bạn, hàng 2 có một đứa con cũng là tổ tiên của nó, nhưng id của nó vẫn chưa được trả lại.

Nói cách khác, CONNECT_BY_ISCYCLE kiểm tra trẻ em (chưa được trả lại), trong khi CYCLE kiểm tra hàng hiện tại (đã được trả lại).

CONNECT BY là dựa trên hàng, trong khi CTE đệ quy là dựa trên thiết lập.

Lưu ý rằng tài liệu của Oracle về CYCLE đề cập đến một "hàng tổ tiên". Tuy nhiên, nói chung, không có khái niệm "hàng tổ tiên" trong CTE đệ quy . Đó là một hoạt động dựa trên tập hợp có thể mang lại kết quả hoàn toàn ngoài gốc cây. Nói chung, phần neo và phần đệ quy thậm chí có thể sử dụng các bảng khác nhau.

Kể từ khi CTE đệ quy là thường là được sử dụng để xây dựng cây phân cấp, Oracle quyết định thêm một kiểm tra chu kỳ. Nhưng do cách dựa trên tập hợp nên CTE đệ quy của hoạt động, thường không thể biết bước tiếp theo có tạo ra một chu trình hay không, bởi vì nếu không có định nghĩa rõ ràng về điều kiện chu trình "hàng tổ tiên" cũng không thể được xác định.

Để thực hiện bước "tiếp theo", toàn bộ tập hợp "hiện tại" cần phải có sẵn, nhưng để tạo mỗi hàng của tập hợp hiện tại (bao gồm cột chu kỳ), chúng ta chỉ cần có kết quả của thao tác "tiếp theo".

Sẽ không có vấn đề gì nếu tập hợp hiện tại luôn bao gồm một hàng (như trong CONNECT BY ), nhưng đó là một vấn đề nếu hoạt động đệ quy được xác định trên một tập hợp nói chung.

Chưa xem xét Oracle 11 nhưng SQL Server triển khai CTE đệ quy chỉ bằng cách ẩn một CONNECT BY đằng sau chúng, đòi hỏi đặt ra nhiều hạn chế (tất cả đều cấm một cách hiệu quả tất cả các hoạt động dựa trên tập hợp).

PostgreSQL Mặt khác, việc triển khai thực sự dựa trên thiết lập:bạn có thể thực hiện bất kỳ hoạt động nào với phần neo trong phần đệ quy. Tuy nhiên, nó không có bất kỳ phương tiện nào để phát hiện các chu kỳ, vì các chu trình không được xác định ngay từ đầu.

Như đã đề cập trước đây, MySQL không triển khai CTE là hoàn toàn (nó không triển khai HASH JOIN của hoặc MERGE JOIN cũng như, chỉ có các vòng lặp lồng nhau, vì vậy đừng ngạc nhiên nhiều).

Trớ trêu thay, hôm nay tôi nhận được một bức thư về chính chủ đề này, mà tôi sẽ trình bày trong blog của mình.

Cập nhật:

Đệ quy CTE của trong SQL Server không nhiều hơn CONNECT BY trong ngụy trang. Xem bài viết này trong blog của tôi để biết chi tiết gây sốc:

  • SQL Server:CTE đệ quy có thực sự dựa trên bộ không?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Trả lại hàng có giá trị tối đa của một cột cho mỗi nhóm

  2. Làm thế nào để sử dụng Array / Table Parameter cho Oracle (ODP.NET 10g) qua ADO.NET/C#?

  3. Điền một bảng PL / SQL từ một khối trong các biểu mẫu D2k của Oracle

  4. DBCA Tạo cơ sở dữ liệu không hợp lệ REMOTE_LISTENER

  5. ORA-00933:Lệnh SQL không được kết thúc đúng cách