为什么我会出现错误 "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>