在 CMS 系統中,需根據用戶權限動態生成欄位導航樹。需求包含三層邏輯:
np_cms_column_security 中 action_1 = '1')action_1 = '0')V_NP_CTREE_BS使用 Oracle CONNECT BY 遞迴查詢,結合 LAG() 分析函數標記根節點:
CREATE OR REPLACE VIEW V_NP_CTREE_BS AS
SELECT B.* FROM (
SELECT A.*, LAG(A.column_id) OVER (PARTITION BY A.column_id ORDER BY 0) RK
FROM (
SELECT /*+CHOOSE */ t.*
FROM np_cms_column t
WHERE t.is_active = '1'
CONNECT BY PRIOR t.column_id = t.parent_id
START WITH t.column_id IN (
SELECT t.column_id
FROM np_cms_column_security t
WHERE t.subject_id = 'mazj'
AND t.action_1 = '1'
)
) A
) B
WHERE NOT EXISTS (
SELECT 0 FROM (
SELECT DISTINCT d.column_id
FROM np_cms_column d
CONNECT BY PRIOR d.column_id = d.parent_id
START WITH d.column_id IN (
SELECT t.column_id
FROM np_cms_column_security t
WHERE t.subject_id = 'mazj'
AND t.action_1 = '0'
AND EXISTS (
SELECT 0 FROM (
SELECT DISTINCT d.column_id
FROM np_cms_column d
CONNECT BY PRIOR d.column_id = d.parent_id
START WITH d.column_id IN (
SELECT t.column_id
FROM np_cms_column_security t
WHERE t.subject_id = 'mazj'
AND t.action_1 = '1'
)
) C1
WHERE C1.column_id = t.column_id
)
)
AND d.is_active = '1'
) C
WHERE C.column_id = B.column_id AND B.RK IS NULL
) AND B.RK IS NULL
UNION ALL
SELECT c.*, 0 RK FROM np_cms_column c WHERE c.parent_id = 0;
V_NP_CTREE_PA解決欄位樹斷層問題,為無父節點的項目指定虛擬父 ID(預設為 1):
CREATE OR REPLACE VIEW V_NP_CTREE_PA AS
SELECT B.*,
(CASE B.column_id WHEN 1 THEN 0 ELSE NVL(B.father, 1) END) VFA
FROM (
SELECT v.*,
(SELECT vv.column_id FROM V_NP_CTREE_BS vv WHERE vv.column_id = v.parent_id) FATHER
FROM V_NP_CTREE_BS v
) B;
V_NP_CTREE_RS使用 SYS_CONNECT_BY_PATH 生成完整路徑,配合 LPAD 產生縮排,便於前端樹狀顯示:
CREATE OR REPLACE VIEW V_NP_CTREE_RS AS
SELECT D.*, LPAD(' ', 2 * LEVEL - 1) || SYS_CONNECT_BY_PATH(D.COLUMN_NAME, '/') "Path"
FROM (
SELECT c.* FROM V_NP_CTREE_PA c
ORDER BY c.VFA, c.disorder DESC, c.column_id DESC
) D
CONNECT BY PRIOR D.column_id = D.VFA
START WITH D.column_id = 1;
LAG() 識別根節點,NVL() 提供預設值