光标内的光标比较同一列的记录未执行
Cursor within cursor to compare same column's record not executing
我正在开发 PL/SQL 小程序,该程序使用游标将列记录与其自身进行比较。当我执行代码时,它花费了很长时间,似乎陷入了无限循环。
Table Data :-
STD
----
2
1
4
3
6
5
8
7
10
9
12
11
下面是我的代码:-
declare
s number;
s1 number;
c number := 0;
cursor c1 is (select std from data);
cursor c2 is (select std from data);
begin
open c1;
loop
fetch c1 into s;
open c2;
loop
fetch c2 into s1;
if s < s1
then
c := c + 1;
end if;
end loop;
insert into con values(c);
close c2;
end loop;
close c1;
end;
/
预期结果:-
C=10
C=10
C=8
C=8
C=6
C=6
C=4
C=4
C=2
C=2
C=0
C=null
你应该添加
EXIT WHEN c1%NOTFOUND;
EXIT WHEN c2%NOTFOUND;
在相应的获取之后。例如
declare
s number;
s1 number;
c number := 0;
cursor c1 is (select std from data);
cursor c2 is (select std from data);
begin
open c1;
loop
fetch c1 into s;
EXIT WHEN c1%NOTFOUND;
open c2;
loop
fetch c2 into s1;
EXIT WHEN c2%NOTFOUND;
if s < s1
then
c := c + 1;
end if;
end loop;
insert into con values(c);
close c2;
end loop;
close c1;
end;
/
如果我理解得很好,您是在假设您的数据以某种方式按照您发布的方式排序;鉴于此,您需要为数据集中的每个值计算大于当前值并出现在当前行之后的值的数量。
假设我们可以考虑使用额外的列 (ID
) 对您的数据样本进行排序:
create table data(ID, std) as (
select 1, 2 from dual union all
select 2, 1 from dual union all
select 3, 4 from dual union all
select 4, 3 from dual union all
select 5, 6 from dual union all
select 6, 5 from dual union all
select 7, 8 from dual union all
select 8, 7 from dual union all
select 9, 10 from dual union all
select 10, 9 from dual union all
select 11, 12 from dual union all
select 12, 11 from dual
)
如果我很了解你的需求,你可以避免使用 PLSQL 和游标,并通过单个查询获得结果:
select d1.std, count(d2.id)
from data d1
left outer join data d2
on ( d1.ID < d2.ID and d2.std > d1.std)
group by d1.std, d1.id
order by d1.ID
在样本数据上,这给出了:
STD COUNT(D2.ID)
---------- ------------
2 10
1 10
4 8
3 8
6 6
5 6
8 4
7 4
10 2
9 2
12 0
11 0
我正在开发 PL/SQL 小程序,该程序使用游标将列记录与其自身进行比较。当我执行代码时,它花费了很长时间,似乎陷入了无限循环。
Table Data :-
STD
----
2
1
4
3
6
5
8
7
10
9
12
11
下面是我的代码:-
declare
s number;
s1 number;
c number := 0;
cursor c1 is (select std from data);
cursor c2 is (select std from data);
begin
open c1;
loop
fetch c1 into s;
open c2;
loop
fetch c2 into s1;
if s < s1
then
c := c + 1;
end if;
end loop;
insert into con values(c);
close c2;
end loop;
close c1;
end;
/
预期结果:-
C=10
C=10
C=8
C=8
C=6
C=6
C=4
C=4
C=2
C=2
C=0
C=null
你应该添加
EXIT WHEN c1%NOTFOUND;
EXIT WHEN c2%NOTFOUND;
在相应的获取之后。例如
declare
s number;
s1 number;
c number := 0;
cursor c1 is (select std from data);
cursor c2 is (select std from data);
begin
open c1;
loop
fetch c1 into s;
EXIT WHEN c1%NOTFOUND;
open c2;
loop
fetch c2 into s1;
EXIT WHEN c2%NOTFOUND;
if s < s1
then
c := c + 1;
end if;
end loop;
insert into con values(c);
close c2;
end loop;
close c1;
end;
/
如果我理解得很好,您是在假设您的数据以某种方式按照您发布的方式排序;鉴于此,您需要为数据集中的每个值计算大于当前值并出现在当前行之后的值的数量。
假设我们可以考虑使用额外的列 (ID
) 对您的数据样本进行排序:
create table data(ID, std) as (
select 1, 2 from dual union all
select 2, 1 from dual union all
select 3, 4 from dual union all
select 4, 3 from dual union all
select 5, 6 from dual union all
select 6, 5 from dual union all
select 7, 8 from dual union all
select 8, 7 from dual union all
select 9, 10 from dual union all
select 10, 9 from dual union all
select 11, 12 from dual union all
select 12, 11 from dual
)
如果我很了解你的需求,你可以避免使用 PLSQL 和游标,并通过单个查询获得结果:
select d1.std, count(d2.id)
from data d1
left outer join data d2
on ( d1.ID < d2.ID and d2.std > d1.std)
group by d1.std, d1.id
order by d1.ID
在样本数据上,这给出了:
STD COUNT(D2.ID)
---------- ------------
2 10
1 10
4 8
3 8
6 6
5 6
8 4
7 4
10 2
9 2
12 0
11 0