10g樹形查詢新特性CONNECT_BY_ISCYCLE的9i實現方式(一)
在10g中Oracle提供了新的偽列:CONNECT_BY_ISCYCLE,透過這個偽列,可以判斷是否在樹形查詢的過程中構成了迴圈,這個偽列只是在CONNECT BY NOCYCLE方式下有效。
這一篇描述一下解決問題的思路。
CONNECT_BY_ISCYCLE的實現和前面兩篇文章中CONNECT_BY_ROOT和CONNECT_BY_ISLEAF的實現完全不同。
因為要實現CONNECT_BY_ISCYCLE,就必須先實現CONNECT BY NOCYCLE,而在9i中是沒有方法實現這個功能的。
也就是說,首先要實現自己的樹形查詢的功能,而僅這第一點,就是一個異常困難的問題,何況後面還要實現NOCYCLE,最後再加上一個ISCYCLE的判斷。
所以總的來說,這個功能的實現比前面兩個功能要複雜得多。由於樹形查詢的LEVEL是不固定的,所以採用連結的方式實現,基本上是不現實的。換句話說,用純SQL的方式來實現樹形查詢的功能基本上不可行。而為了解決這個功能,只能透過PL/SQL配合SQL來實現。
仍然是首先構造一個例子:
SQL> CREATE TABLE T_TREE (ID NUMBER, FATHER_ID NUMBER, NAME VARCHAR2(30));
表已建立。
SQL> INSERT INTO T_TREE VALUES (1, 0, 'A');
已建立 1 行。
SQL> INSERT INTO T_TREE VALUES (2, 1, 'BC');
已建立 1 行。
SQL> INSERT INTO T_TREE VALUES (3, 1, 'DE');
已建立 1 行。
SQL> INSERT INTO T_TREE VALUES (4, 1, 'FG');
已建立 1 行。
SQL> INSERT INTO T_TREE VALUES (5, 2, 'HIJ');
已建立 1 行。
SQL> INSERT INTO T_TREE VALUES (6, 4, 'KLM');
已建立 1 行。
SQL> INSERT INTO T_TREE VALUES (7, 6, 'NOPQ');
已建立 1 行。
SQL> INSERT INTO T_TREE VALUES (0, 0, 'ROOT');
已建立 1 行。
SQL> INSERT INTO T_TREE VALUES (4, 7, 'FG');
已建立 1 行。
SQL> COMMIT;
提交完成。
SQL> SELECT * FROM T_TREE;
ID FATHER_ID NAME
---------- ---------- ------------------------------
1 0 A
2 1 BC
3 1 DE
4 1 FG
5 2 HIJ
6 4 KLM
7 6 NOPQ
0 0 ROOT
4 7 FG
已選擇9行。
上面構造了兩種樹形查詢迴圈的情況,一種是當前記錄的自迴圈,另一種是樹形查詢的某個子節點是當前節點的祖先節點,從而構成了迴圈。在這個例子中,記錄ID為0和ID為4且FATHER_ID等於7的兩條記錄分別構成了上述的兩種迴圈的情況。
下面就來看看CONNECT_BY_ISCYCLE和CONNECT BY NOCYCLE的功能:
SQL> SELECT *
2 FROM T_TREE
3 START WITH ID = 0
4 CONNECT BY PRIOR ID = FATHER_ID;
ERROR:
ORA-01436: 使用者資料中的 CONNECT BY 迴圈
未選定行
SQL> SELECT *
2 FROM T_TREE
3 START WITH ID = 1
4 CONNECT BY PRIOR ID = FATHER_ID;
ERROR:
ORA-01436: 使用者資料中的 CONNECT BY 迴圈
未選定行
這就是不使用CONNECT BY NOCYCLE的情況,查詢會報錯,指出樹形查詢中出現迴圈,在10g中可以使用CONNECT BY NOCYCLE的方式來避免錯誤的產生:
SQL> SELECT *
2 FROM T_TREE
3 START WITH ID = 0
4 CONNECT BY NOCYCLE PRIOR ID = FATHER_ID;
ID FATHER_ID NAME
---------- ---------- ------------------------------
0 0 ROOT
1 0 A
2 1 BC
5 2 HIJ
3 1 DE
4 1 FG
6 4 KLM
7 6 NOPQ
已選擇8行。
使用CONNECT BY NOCYCLE,Oracle自動避免迴圈的產生,將不產生迴圈的資料查詢出來,下面看看CONNECT_BY_ISCYCLE的功能:
SQL> SELECT ID,
2 FATHER_ID,
3 NAME,
4 CONNECT_BY_ISCYCLE CYCLED
5 FROM T_TREE
6 START WITH ID = 0
7 CONNECT BY NOCYCLE PRIOR ID = FATHER_ID;
ID FATHER_ID NAME CYCLED
---------- ---------- ------------------------------ ----------
0 0 ROOT 1
1 0 A 0
2 1 BC 0
5 2 HIJ 0
3 1 DE 0
4 1 FG 0
6 4 KLM 0
7 6 NOPQ 1
已選擇8行。
可以看到,CONNECT_BY_ISCYCLE偽列指出迴圈在樹形查詢中發生的位置。
為了實現CONNECT_BY_ISCYCLE就必須先實現CONNECT BY NOCYCLE方式,而這在9i中是沒有現成的辦法的,所以這裡嘗試使用PL/SQL來自己實現樹形查詢的功能。
SQL> CREATE OR REPLACE FUNCTION F_FIND_CHILD(P_VALUE VARCHAR2) RETURN VARCHAR2 AS
2 V_STR VARCHAR2(32767) := '/' || P_VALUE;
3
4 PROCEDURE P_GET_CHILD_STR (P_FATHER IN VARCHAR2, P_STR IN OUT VARCHAR2) AS
5 BEGIN
6 FOR I IN (SELECT ID FROM T_TREE WHERE FATHER_ID = P_FATHER AND FATHER_ID != ID) LOOP
7 IF INSTR(P_STR || '/', '/' || I.ID || '/') = 0 THEN
8 P_STR := P_STR || '/' || I.ID;
9 P_GET_CHILD_STR(I.ID, P_STR);
10 END IF;
11 END LOOP;
12 END;
13 BEGIN
14 P_GET_CHILD_STR(P_VALUE, V_STR);
15 RETURN V_STR;
16 END;
17 /
函式已建立。
構造一個函式,在函式中遞迴呼叫過程來實現樹形查詢的功能。
下面看看呼叫這個函式的結果:
SQL> SELECT F_FIND_CHILD(0) FROM DUAL;
F_FIND_CHILD(0)
------------------------------------------------
/0/1/2/5/3/4/6/7
SQL> SELECT F_FIND_CHILD(2) FROM DUAL;
F_FIND_CHILD(2)
------------------------------------------------
/2/5
SQL> SELECT F_FIND_CHILD(4) FROM DUAL;
F_FIND_CHILD(4)
------------------------------------------------
/4/6/7
雖然目前存在的問題還有很多,但是已經基本上實現了一個最簡單的NOCYCLE的SYS_CONNECT_BY_PATH的功能。
有了這個函式作為基礎,就可以逐步的實現最終的目標了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-405453/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 10g樹形查詢新特性CONNECT_BY_ISCYCLE的9i實現方式(四)
- 10g樹形查詢新特性CONNECT_BY_ISCYCLE的9i實現方式(三)
- 10g樹形查詢新特性CONNECT_BY_ISCYCLE的9i實現方式(二)
- 10g樹形查詢新特性CONNECT_BY_ROOT的9i實現方式
- 10g樹形查詢新特性CONNECT_BY_ISLEAF的9i實現方式
- LightDB 22.4 新特性之相容Oracle樹形查詢Oracle
- 樹形查詢
- 10g新特性——閃回版本查詢
- oracle樹形查詢Oracle
- 利用樹形查詢實現部分分析函式功能函式
- Oracle Database 10g新特性-閃回版本查詢OracleDatabase
- java實現Hbase中的查詢(一)Filter方式JavaFilter
- Elasticsearch 查詢in 和 not in 的實現方式Elasticsearch
- oracle樹形選單查詢Oracle
- Connect by實現樹查詢的妙用
- 樹形結構的儲存與查詢
- Oracle 樹形結構查詢的特殊用法Oracle
- ORACLE 樹形查詢(connect by...start with...)的應用(一)Oracle
- 遞迴樹形查詢所有分類遞迴
- Mysql 實現樹狀遞迴查詢MySql遞迴
- NKMySQL 查詢樹結構方式gllMySql
- 二叉查詢樹的實現——C++C++
- 利用CGI方式實現Web查詢 (轉)Web
- 樹形查詢也瘋狂&優化措施優化
- Java實現遞迴查詢樹結構Java遞迴
- 二叉查詢樹概念及實現
- C#實現二叉查詢樹C#
- 聊聊mysql的樹形結構儲存及查詢MySql
- 使用JS去實現一個BST(二叉查詢樹)JS
- 在Oracle 10g和9i上對於開發者一些新的特性的總結Oracle 10g
- #MyBatis多表查詢 #多對一、一對多的兩種實現方式 @FDDLCMyBatis
- MySQL 實現樹形的遍歷MySql
- 轉:C++實現的變種二分查詢法(折半查詢)--二叉查詢樹C++
- JavaScript實現簡單二叉查詢樹JavaScript
- 樹形結構的選單表設計與查詢
- 使用 Redis 解決“樹”形資料的複雜查詢Redis
- 一個簡單的樹查詢
- MySQL實現樹狀所有子節點查詢的方法MySql