如果没有匹配的记录,则返回代码

时间:2013-06-01 10:03:14

标签: sql oracle plsql

我正在尝试在PL / SQL中编写一个带有一个参数pname的函数,并返回pname(玩家姓名)在他最喜欢的体育场玩了多少次。这部分主要按预期工作。我的问题是我正在尝试添加的错误处理。即

  • 如果players.name中不存在pname,则返回-2
  • 如果favestadiums.player中不存在pname,则返回-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;

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

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

非常感谢帮助。

修改:

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

enter image description here

3 个答案:

答案 0 :(得分:0)

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

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

当您在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子句中的额外一个。

答案 1 :(得分:0)

您的查询看起来并不正确,因为它会同时尝试太多内容。

players.name以pname的形式给出,因此您无需从查询中返回它。你只想要一个玩家的结果,因此你不需要在players.name上分组。

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

然后编写一个查询,在fav_statium_count中只存储给定玩家的总和(...)。此类查询只有两种可能的结果:如果播放器没有结果,则fav_statdim_count为null,或者是0的计数。

答案 2 :(得分: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;