您没有指定您使用的 Oracle 数据库版本。
如果是 11g,那么fetch 子句将不起作用(因为它还不存在):
SQL> select * from dept
2 fetch next 1 rows only;
fetch next 1 rows only
*
ERROR at line 2:
ORA-00933: SQL command not properly ended
另一个答案建议根本不要使用游标或循环 - 这完全有道理,但是你必须编写更多代码以避免TOO_MANY_ROWS(因为你不能将两行放入标量变量中)和,可能是NO_DATA_FOUND。有了游标,您就不必担心,因为 Oracle 会为您处理它。
因此,您可以按照您的描述进行 - 只运行一次循环迭代。但是,完全使用循环吗?只需open - fetch - close。这意味着您的代码可能看起来像这样(基于 Scott 的示例架构,因为我没有您的表)。
“模拟”您的查询会获取每个部门的工资总额。我对最高薪水感兴趣。
SQL> select d.dname, sum(e.sal) sumsal
2 from emp e join dept d on d.deptno = e.deptno
3 group by d.dname
4 order by sumsal desc;
DNAME SUMSAL
-------------- ----------
RESEARCH 10875 --> that's what I want
SALES 9400
ACCOUNTING 8750
程序:
SQL> declare
2 cursor find_c is
3 select d.dname, sum(e.sal) sumsal
4 from emp e join dept d on d.deptno = e.deptno
5 group by d.dname
6 order by sumsal desc;
7 cur_r find_c%rowtype;
8 lv_dname dept.dname%type;
9 begin
10 open find_c;
11 fetch find_c into cur_r;
12
13 if cur_r.sumsal > 0 then
14 lv_dname := cur_r.dname;
15 end if;
16
17 dbms_output.put_line('Picked DNAME = ' || lv_dname ||
18 '. Now, do something here, execute some more code');
19
20 -- some code goes here
21 dbms_output.put_line('First iteration is over; that''s the end');
22 close find_c;
23 end;
24 /
Picked DNAME = RESEARCH. Now, do something here, execute some more code --> good, RESEARCH is here
First iteration is over; that's the end
PL/SQL procedure successfully completed.
SQL>
只是为了表明没有光标你可能会遇到一些问题:
TOO_MANY_ROWS:
SQL> declare
2 l_dname dept.dname%type;
3 l_sumsal number;
4 begin
5 select d.dname, sum(e.sal) sumsal
6 into l_dname, l_sumsal
7 from emp e join dept d on d.deptno = e.deptno
8 group by d.dname
9 order by sumsal desc;
10 dbms_output.put_line('Query executed');
11 end;
12 /
declare
*
ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 5
NO_DATA_FOUND:
SQL> declare
2 l_dname dept.dname%type;
3 l_sumsal number;
4 begin
5 select d.dname, sum(e.sal) sumsal
6 into l_dname, l_sumsal
7 from emp e join dept d on d.deptno = e.deptno
8 where 1 = 2 --> will cause NO_DATA_FOUND
9 group by d.dname
10 order by sumsal desc;
11 dbms_output.put_line('Query executed');
12 end;
13 /
declare
*
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at line 5
SQL>
当然,您可以解决这个问题(例如,使用异常处理程序部分),但是 - 为什么要麻烦?
[编辑,根据您的评论]
如果游标为每个 ID 返回多于一行并且您想跳过其余行,一个选择是使用 ROW_NUMBER 分析函数对行进行“排序”,然后仅获取每个 ID 的第一行.在我基于 Scott 表格的示例中,它看起来像这样:
cursor find_c is
select dname, sumsal
from (select d.dname, sum(e.sal) sumsal,
row_number() over (partition by d.dname order by sum(e.sal) desc) rn
from emp e join dept d on d.deptno = e.deptno
group by d.dname
)
where rn = 1;
根据您的数据模型调整它。