Получение данных из следующей строки в курсоре Oracle

Я создаю вложенное дерево, и я должен получить данные для следующей строки в курсоре, с помощью 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;
6
задан Daniel Ganiev 15 June 2010 в 06:59
поделиться

3 ответа

Использование функций LEAD и LAG

LEAD может вычислять выражение для следующих строк (строк, которые будут идти после текущей строки) и возвращать значение в текущую строку . Общий синтаксис LEAD показан ниже:

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

sql_expr - это выражение, вычисляемое из первой строки.

смещение - это индекс ведущей строки относительно текущей строки. Смещение - положительное целое число со значением по умолчанию 1.

default - это значение, возвращаемое, если указывает на строку за пределами раздела диапазон.

Синтаксис LAG аналогичен, за исключением того, что смещение для LAG переходит в предыдущие строки.

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.
18
ответ дан 8 December 2019 в 05:20
поделиться

было бы лучше сохранить предыдущий уровень и использовать его. что-то вроде

  /* 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; 
2
ответ дан 8 December 2019 в 05:20
поделиться

Я так и сделал. Я строю дерево на шаг назад. Я должен проверить первую итерацию.

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;
3
ответ дан 8 December 2019 в 05:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: