2010-06-15 39 views
6

Tôi đang xây dựng cây lồng nhau và tôi cần lấy dữ liệu cho hàng tiếp theo trong con trỏ, sử dụng Oracle. Và tôi vẫn cần hàng hiện tại, do đó, lặp đi lặp lại phía trước không phải là một giải pháp. Ví dụ:Lấy dữ liệu từ hàng kế tiếp trong con trỏ Oracle

OPEN emp_cv FOR sql_stmt; 
    LOOP 
    FETCH emp_cv INTO v_rcod,v_rname,v_level; 
    EXIT WHEN emp_cv%NOTFOUND; 
    /*here lies the code for getting v_next_level*/ 
     if v_next_level > v_level then 
      /*code here*/ 
      elsif v_next_level < v_level then 
      /*code here*/ 
      else 
      /*code here*/ 
      end if; 
    END LOOP; 
    CLOSE emp_cv; 

Trả lời

18

Sử dụng LEAD và LAG Chức năng

LEAD có khả năng tính toán một biểu thức trên các hàng tiếp theo (hàng đó sẽ đến sau khi hàng hiện tại) và trả lại giá trị cho hàng hiện tại. Cú pháp chung của LEAD được hiển thị dưới đây:

LEAD (sql_expr, bù đắp, mặc định) OVER (analytic_clause)

sql_expr là biểu thức để tính toán từ hàng hàng đầu.

bù đắp là chỉ số của hàng hàng đầu so với row.offset hiện nay là một số nguyên dương với mặc định 1.

mặc định là giá trị trả về nếu các điểm đến một hàng bên ngoài phân vùng phạm vi.

Cú pháp của LAG tương tự ngoại trừ việc bù đắp cho LAG đi vào các hàng trước đó.

SELECT deptno, empno, sal, 
LEAD(sal, 1, 0) OVER (PARTITION BY dept ORDER BY sal DESC) NEXT_LOW_SAL, 
LAG(sal, 1, 0) OVER (PARTITION BY dept ORDER BY sal DESC) PREV_HIGH_SAL 
FROM emp 
WHERE deptno IN (10, 20) 
ORDER BY deptno, sal DESC; 

DEPTNO EMPNO SAL NEXT_LOWER_SAL PREV_HIGHER_SAL 
------- ------ ----- -------------- --------------- 
    10 7839 5000   2450    0 
    10 7782 2450   1300   5000 
    10 7934 1300    0   2450 
    20 7788 3000   3000    0 
    20 7902 3000   2975   3000 
    20 7566 2975   1100   3000 
    20 7876 1100   800   2975 
    20 7369 800    0   1100 

8 rows selected. 
+0

Tôi đang sử dụng "đặt hàng anh chị em theo tên" và Oracle thề. Nhưng cảm ơn đã cho tôi thấy một chức năng tuyệt vời như vậy. –

2

nó sẽ là tốt hơn để lưu trữ các trước mức và sử dụng. một cái gì đó dọc theo dòng của

/* set to a value lesser than the lowest value possible for level 
    am assuming 0 is the lowest value possible */ 
    v_previous_level := -1; 

    OPEN emp_cv FOR sql_stmt; 
    LOOP 
    FETCH emp_cv INTO v_rcod,v_rname,v_level; 
    EXIT WHEN emp_cv%NOTFOUND; 
     /* you'd probably have to update v_previous_level in one of 
     these conditions (depends on your logic) */ 
     if v_previous_level > v_level then 
      /*code here*/ 
      elsif v_previous_level < v_level then 
      /*code here*/ 
      else 
      /*code here*/ 
      end if; 
    END LOOP; 
    CLOSE emp_cv; 
+0

Thực ra, tôi đã thử nó, nó hoạt động, tất nhiên, nhưng tôi có cấu trúc HTML đặc biệt, cần plugin jQuery và cây tiếp cận này không xây dựng đúng cách. –

3

Tôi đã làm theo cách này. Tôi đang xây dựng một cái cây trong một bước lùi. Tôi phải kiểm tra lần lặp đầu tiên.

OPEN emp_cv FOR sql_stmt; 
LOOP  
if emp_cv%notfound then 
    /*some code*/ 
    exit; 
end if; 
FETCH emp_cv INTO v_new_level;  
    if not b_first_time then  
     if v_new_level > v_level then 
     /*some code*/ 
     elsif v_new_level < v_level then    
     /*some code*/ 
     else 
     /*code*/ 
     end if; 
    else  
     b_first_time:=false; 
    end if; 
     v_level:=v_new_level;  
    END LOOP; 
    CLOSE emp_cv; 
Các vấn đề liên quan