从 Oracle 游标中的下一行获取数据
Posted
技术标签:
【中文标题】从 Oracle 游标中的下一行获取数据【英文标题】:Getting data from the next row in Oracle cursor 【发布时间】:2010-06-15 06:59:53 【问题描述】:我正在构建嵌套树,我需要使用 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;
【问题讨论】:
【参考方案1】:使用 LEAD 和 LAG 函数
LEAD 能够计算下一行(将在当前行之后的行)的表达式并将值返回到当前行。 LEAD 的一般语法如下所示:
LEAD (sql_expr, offset, default) OVER (analytic_clause)
sql_expr 是从前导行计算的表达式。
offset是前导行相对于当前行的索引。offset是一个正整数,默认为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.
【讨论】:
我正在使用“按名称排序兄弟姐妹”,Oracle 发誓。但是感谢您向我展示了如此出色的功能。【参考方案2】:我是这样做的。我正在倒退一步地建造一棵树。我必须检查第一次迭代。
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】:存储上一个级别并使用它会更好吗?类似于
/* 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;
【讨论】:
其实我已经试过了,它当然可以,但是我有特殊的 html 结构,这是 jQuery 插件所需要的,并且这种方法树无法正确构建。以上是关于从 Oracle 游标中的下一行获取数据的主要内容,如果未能解决你的问题,请参考以下文章