0

我正在尝试用 PL/SQL 编写一个函数,该函数接受一个参数 ,并返回在他最喜欢的体育场打过pname多少次(球员姓名)。pname这部分主要按预期工作。我的问题是我试图添加的错误处理。即

  • 如果pnameplayer.name 中不存在则返回 -2
  • 如果pnamefavstadiums.player 中不存在则返回 -1

这就是我所拥有的(已转换为评论的部分是我想要弄清楚的):

create or replace function favS(pname varchar2) return number
as
    fav_stadium_count number;
    vplayername varchar(100);
begin
    select sum(case when favstadiums.stadium = matches.stadium then 1 else 0 end),
    players.name into fav_stadium_count, vplayername
    from favstadiums
    full outer join players
    on favstadiums.player = players.name
    full outer join matches
    on favstadiums.stadium = matches.stadium
    where name = pname
    and players.team in (matches.home, matches.away)
    group by players.name;
    if (fav_stadium_count >= 0) then
        return fav_stadium_count;
    end if;
    -- if (pname not in players.name) then
    --  return -2;
    -- end if;
    -- if (pname not in favstadiums.player) then
    --  return -1;
    -- end if;
end;

我尝试将 player.name 存储为变量vplayername并使用if (pname not in vplayername) then...,但这不会返回任何值,而不是-2.

我没有与错误处理相关的另一个单独问题是fav_stadium_count永远不会返回计数 0。

帮助将不胜感激。

编辑:

如果有帮助,这是关系图(我知道它看起来不寻常,但我没有创建它):

在此处输入图像描述

4

3 回答 3

0

如果您的基本查询是正确的,您可以在之后使用单独的查询来测试这两个条件:

declare cnt number;

. . .

select count(*) into cnt from players where players.name = pname;

if cnt = 0 then
    return -2;

select count(*) into cnt from fav_stadiums where fs.player = pname;

if cnt = 0 then
    return -1;
于 2013-06-01T14:31:41.687 回答
0

我不太喜欢返回错误代码,但我猜它有时很有用。如果你想这样做你需要知道它是否存在于表中,这意味着你需要选择它......

如果它存在,即它不为空,那么你有一个,如果它为空,那么播放器不存在。

当您选择WHERE players.name = pname名称时,PLAYERS始终存在。所以,这似乎有点毫无意义,同样,我不确定你为什么要进行所有的 FULL OUTER JOIN,你可能应该有外键来确保你的数据是一致的。是否有可能让某个玩家进入FAVSTADIUMS其中不存在的玩家PLAYERS

create or replace function favS(pname varchar2) return number is

    l_fav_stadium_count number;
    l_player_exists players.name%type;
    l_favstadiums_exists favstadiums.player%type;

begin

    select sum(case when favstadiums.stadium = matches.stadium then 1 else 0 end)
         , players.name
         , favstadiums.player
      into l_fav_stadium_count, l_player_exists, l_favstadiums_exists
      from favstadiums
      full outer join players
        on favstadiums.player = players.name
      full outer join matches
        on favstadiums.stadium = matches.stadium
     where name = pname
       and players.team in (matches.home, matches.away)
     group by players.name
            , favstadiums.player;

    if l_fav_stadium_count >= 0 then
        return l_fav_stadium_count;
    elsif l_player_exists is null then
        return -2;
    elsif l_favstadiums_exists is null then
        return -1;
    end if;

end;
/

当您加入球员姓名时,在 GROUP BY 子句中包含一个额外的名字应该没有问题。

于 2013-06-01T10:14:24.383 回答
0

您的查询看起来不正确,因为它一次尝试了太多事情。

player.name 以 pname 形式给出,因此您无需从查询中返回它。您只需要一个玩家的结果,因此您不需要对 player.name 进行分组。

首先使用单独的查询来检查 pname 是否是有效的球员,然后检查它是否与体育场相连。如果检查失败,请在此处返回负值。

然后编写一个查询,仅将给定玩家的 sum(...) 存储在 fav_statium_count 中。这样的查询只有两种可能的结果:如果玩家没有结果,fav_statdim_count 为 null,或者它是从 0 开始的计数。

于 2013-06-01T10:32:36.500 回答