tags:

views:

76

answers:

3

Hi, I'm building nested tree and I need to get data for the next row in cursor, using Oracle. And I still need current row, so looping forward is not a solution. Example:

  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;
+2  A: 

would it be better to store the previous level and use that. something along the lines of

  /* 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; 
potatopeelings
Actually, I already tried it, it works, of course, but I have got special HTML structure, that is needed by jQuery plugin, and with this approach tree is not building properly.
Chaotic_one
+9  A: 

Use LEAD and LAG Functions

LEAD has the ability to compute an expression on the next rows (rows which are going to come after the current row) and return the value to the current row. The general syntax of LEAD is shown below:

LEAD (sql_expr, offset, default) OVER (analytic_clause)

sql_expr is the expression to compute from the leading row.

offset is the index of the leading row relative to the current row.offset is a positive integer with default 1.

default is the value to return if the points to a row outside the partition range.

The syntax of LAG is similar except that the offset for LAG goes into the previous rows.

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.
Bharat
I'm using "order siblings by name", and Oracle swears. But thanks for showing me such a great functions.
Chaotic_one
+1  A: 

I did it this way. I'm building a tree in a step backwards. I have to check for the first iteration.

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;
Chaotic_one