oracle - 为什么我有一个错误“精确提取返回的行数超过了请求的行数”?
问题描述
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 只包含一行,否则这将返回too_many_rows
.
除此之外,还有几种SELECT DISTINCT
说法。如果DISTINCT
不做它的工作,那么要么你的数据是错误的,要么你的代码是错误的。WHERE
也许您需要在子句中添加另一个条件。
无论哪种语句返回错误,最简单的选择是使用聚合函数之一,例如
select max(cx.uni_name) ...
因为它只会返回一个值,但是 - 这很可能是您应该使用的最后一个选项。
[编辑]
等一下; 是的,您遇到了各种错误,但是 - 更仔细地查看您的代码,这没有多大意义。首先,它应该是一个函数,而不是一个过程:
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
您正在从同一个表中选择一个游标变量值到参数中,游标select
是基于if
s 没用。是in
用城市表示的参数;您不必对这些值进行硬编码,因为如果表中有更多引用,该过程可能会成为一个真正的怪物
很快,我建议您使用我在上面发布的功能。
[编辑#2]
根据您的评论:一个城市可以有几所大学。因此,您不能返回标量值,而是返回其他值,例如 ref 游标或数组。
假设这是您拥有的表:
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>
推荐阅读
- php - Laravel 重复的包名
- android - Android导航组件打开url
- php - json风格的mongodb php查询
- python-3.x - TensorFlow 检查失败:work_element_count > 0
- docker - 从 docker-compose 启动特定服务
- php - MySQL使用另一个表中的值过滤一个表中的数据
- python - 在 Django 中一次获取数据并在整个应用程序中使用
- graphics - 直接采样灯光时如何计算PDF
- node.js - Create-React-App 需要 Node 4.0 或更高版本 - 在 Windows 上
- php - 向 HelloSign 模板添加超链接