为什么我会出现错误 "exact fetch returns more than requested number of rows"?
Why do I have an error "exact fetch returns more than requested number of rows"?
1. create or replace procedure cities (
2. vname in varchar2,
3. vuni out varchar2
4. ) as
5. cursor c is
6. select city_name, uni_name from uni ;
7. cx c%rowtype;
8. begin
9. select uni_name into vuni from uni;
10. open c;
11. loop
12. fetch c into cx;
13. exit when c%notfound;
14. if (vname = 'Almaty') then
15. select distinct cx.uni_name into vuni from uni where cx.city_name = vname;
16. elsif (vname = 'Nur-Sultan') then
17. select distinct cx.uni_name into vuni from uni where cx.city_name = vname;
18. elsif (vname = 'Aktau') then
19. select distinct cx.uni_name into vuni from uni where cx.city_name = vname;
20. else
21. select distinct cx.uni_name into vuni from uni where cx.city_name = vname;
22. end if;
23. end loop;
24. close c;
25. end;
检查游标外的所有 SELECT
语句。
第 9 行第一个最可疑:
select uni_name into vuni from uni;
除非UNI
table只包含一行,这将return too_many_rows
.
除此之外,还有几个SELECT DISTINCT
声明。如果 DISTINCT
没有完成它的工作,那么要么是你的数据有误,要么是你的代码有误。也许您需要在 WHERE
子句中添加另一个条件。
无论哪个语句 return 出错,最简单的选择是使用聚合函数之一,例如
select max(cx.uni_name) ...
因为它将 return 只有一个值,但是 - 这很可能是您应该使用的最后一个选项。
[编辑]
等一下;是的,您遇到了各种错误,但是 - 更仔细地查看您的代码,它没有多大意义。首先,它应该是一个函数,而不是一个过程:
create or replace function f_cities (par_vname in varchar2)
return uni.uni_name%type
is
retval uni.uni_name%type;
begin
select u.uni_name
into retval
from u.uni
where u.city_name = par_vname;
return retval;
end;
如果必须是程序,那么
create or replace procedure cities
(par_vname in varchar2,
par_vuni out varchar2
)
is
begin
select u.uni_name
into par_vuni
from u.uni
where u.city_name = par_vname;
end;
根据您的代码:
- 您使用的光标不是必需的
select
语句好奇怪;您在 OUT
参数中选择一个游标变量值,来自同一个 table 游标的 select
基于
if
没用。它是 in
参数,表示它是城市;您不必对这些值进行硬编码,因为如果 table 中有更多引用,该过程可能会变成一个真正的怪物
不久,我建议您使用我在上面发布的功能。
[编辑 #2]
根据您的评论:一个城市可以有多所大学。因此,您不能 return 标量值,而是 其他东西 ,例如引用游标或数组。
假设这是 table 你有:
SQL> create table uni
2 (city_name varchar2(20),
3 uni_name varchar2(20));
Table created.
SQL> insert into uni (city_name, uni_name)
2 select 'Almaty', 'Uni 1' from dual union all
3 select 'Almaty', 'Uni2' from dual union all
4 select 'Nur-Sultan', 'Uni 4' from dual union all
5 select 'Aktau', 'Uni 3' from dual union all
6 select 'Aktau', 'Uni 9' from dual;
5 rows created.
SQL>
现在您可以执行以下操作:
SQL> create or replace function f_uni (par_city_name in varchar2)
2 return sys.odcivarchar2list
3 as
4 rc sys.odcivarchar2list;
5 begin
6 select uni_name
7 bulk collect into rc
8 from uni
9 where city_name = par_city_name;
10 return rc;
11 end;
12 /
Function created.
SQL> select f_uni('Almaty') from dual;
F_UNI('ALMATY')
--------------------------------------------------------------------------------
ODCIVARCHAR2LIST('Uni 1', 'Uni2')
或
SQL> create or replace function f_uni (par_city_name in varchar2)
2 return sys_refcursor
3 as
4 rc sys_refcursor;
5 begin
6 open rc for select uni_name
7 from uni
8 where city_name = par_city_name;
9 return rc;
10 end;
11 /
Function created.
SQL> select f_uni('Almaty') from dual;
F_UNI('ALMATY')
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
UNI_NAME
--------------------
Uni 1
Uni2
SQL>
1. create or replace procedure cities (
2. vname in varchar2,
3. vuni out varchar2
4. ) as
5. cursor c is
6. select city_name, uni_name from uni ;
7. cx c%rowtype;
8. begin
9. select uni_name into vuni from uni;
10. open c;
11. loop
12. fetch c into cx;
13. exit when c%notfound;
14. if (vname = 'Almaty') then
15. select distinct cx.uni_name into vuni from uni where cx.city_name = vname;
16. elsif (vname = 'Nur-Sultan') then
17. select distinct cx.uni_name into vuni from uni where cx.city_name = vname;
18. elsif (vname = 'Aktau') then
19. select distinct cx.uni_name into vuni from uni where cx.city_name = vname;
20. else
21. select distinct cx.uni_name into vuni from uni where cx.city_name = vname;
22. end if;
23. end loop;
24. close c;
25. end;
检查游标外的所有 SELECT
语句。
第 9 行第一个最可疑:
select uni_name into vuni from uni;
除非UNI
table只包含一行,这将return too_many_rows
.
除此之外,还有几个SELECT DISTINCT
声明。如果 DISTINCT
没有完成它的工作,那么要么是你的数据有误,要么是你的代码有误。也许您需要在 WHERE
子句中添加另一个条件。
无论哪个语句 return 出错,最简单的选择是使用聚合函数之一,例如
select max(cx.uni_name) ...
因为它将 return 只有一个值,但是 - 这很可能是您应该使用的最后一个选项。
[编辑]
等一下;是的,您遇到了各种错误,但是 - 更仔细地查看您的代码,它没有多大意义。首先,它应该是一个函数,而不是一个过程:
create or replace function f_cities (par_vname in varchar2)
return uni.uni_name%type
is
retval uni.uni_name%type;
begin
select u.uni_name
into retval
from u.uni
where u.city_name = par_vname;
return retval;
end;
如果必须是程序,那么
create or replace procedure cities
(par_vname in varchar2,
par_vuni out varchar2
)
is
begin
select u.uni_name
into par_vuni
from u.uni
where u.city_name = par_vname;
end;
根据您的代码:
- 您使用的光标不是必需的
select
语句好奇怪;您在OUT
参数中选择一个游标变量值,来自同一个 table 游标的select
基于if
没用。它是in
参数,表示它是城市;您不必对这些值进行硬编码,因为如果 table 中有更多引用,该过程可能会变成一个真正的怪物
不久,我建议您使用我在上面发布的功能。
[编辑 #2]
根据您的评论:一个城市可以有多所大学。因此,您不能 return 标量值,而是 其他东西 ,例如引用游标或数组。
假设这是 table 你有:
SQL> create table uni
2 (city_name varchar2(20),
3 uni_name varchar2(20));
Table created.
SQL> insert into uni (city_name, uni_name)
2 select 'Almaty', 'Uni 1' from dual union all
3 select 'Almaty', 'Uni2' from dual union all
4 select 'Nur-Sultan', 'Uni 4' from dual union all
5 select 'Aktau', 'Uni 3' from dual union all
6 select 'Aktau', 'Uni 9' from dual;
5 rows created.
SQL>
现在您可以执行以下操作:
SQL> create or replace function f_uni (par_city_name in varchar2)
2 return sys.odcivarchar2list
3 as
4 rc sys.odcivarchar2list;
5 begin
6 select uni_name
7 bulk collect into rc
8 from uni
9 where city_name = par_city_name;
10 return rc;
11 end;
12 /
Function created.
SQL> select f_uni('Almaty') from dual;
F_UNI('ALMATY')
--------------------------------------------------------------------------------
ODCIVARCHAR2LIST('Uni 1', 'Uni2')
或
SQL> create or replace function f_uni (par_city_name in varchar2)
2 return sys_refcursor
3 as
4 rc sys_refcursor;
5 begin
6 open rc for select uni_name
7 from uni
8 where city_name = par_city_name;
9 return rc;
10 end;
11 /
Function created.
SQL> select f_uni('Almaty') from dual;
F_UNI('ALMATY')
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
UNI_NAME
--------------------
Uni 1
Uni2
SQL>