PL / SQL函数编译错误

时间:2013-05-31 09:23:55

标签: sql oracle plsql

我正在尝试编写一个PL / SQL函数,该函数将播放器的名称作为参数,并返回在他最喜欢的体育场中播放的匹配数。

如果播放器表中不存在播放器,则该函数应返回-2。如果玩家存在但他没有任何喜欢的体育场,则该函数返回-1。

这就是我所拥有的:

create or replace function favS(pname varchar2) return number
as
    fav_stadium_count number;
begin
    select count(case when favstadiums.stadium = matches.stadium then 1 else null end) into fav_stadium_count
    from favstadiums
    right join players
    on favstadiums.player = players.name
    outer join matches
    on favstadiums.stadium = matches.stadium;
    if (count(case when favstadiums.stadium = matches.stadium then 1 else null end) > 0) then
        return fav_stadium_count;
    end if;
    if players.name is null then
        return -2;
    end if;
    if (count(case when favstadiums.stadium = matches.stadium then 1 else null end) < 1) then
        return -1;
    end if;
end;

但是我收到以下编译错误:

Line 9: ORA-00933: SQL command not properly ended
Line 5: SQL Statement ignored

有关如何解决此问题的任何想法?

如果有帮助,这是数据库的关系图:

enter image description here

编辑(针对特德):

create or replace function favS(pname varchar2) return number
as
    fav_stadium_count number;
    vplayername varchar(100);
begin
    select count(case when favstadiums.stadium = matches.stadium then 1 else null end) into fav_stadium_count,
    players.name into vplayername
    from favstadiums
    right join players
    on favstadiums.player = players.name
    left outer join matches
    on favstadiums.stadium = matches.stadium
    where name = pname;
    if (fav_stadium_count > 0) then
        return fav_stadium_count;
    end if;
    if vplayername is null then
        return -2;
    end if;
    if (fav_stadium_count < 1) then
        return -1;
    end if;
end;

3 个答案:

答案 0 :(得分:3)

if (count(case when favstadiums.stadium = matches.stadium then 1 else null end) > 0) then
   return fav_stadium_count;
end if;

应该是:

if (fav_stadium_count > 0) then
   return fav_stadium_count;
end if;

至于以下声明:

if players.name is null then
   return -2;
end if;

也是错的。那里也没有选择声明。您应该使用某种变量(如fav_stadium_count)来存储您想要的名称。

if (count(case when favstadiums.stadium = matches.stadium then 1 else null end) < 1) then
    return -1;
end if;

应该成为:

if (fav_stadium_count < 1) then
    return -1;
end if;

答案 1 :(得分:0)

我认为你的联接语法不正确。尝试:INNER JOIN和LEFT OUTER JOIN。在没有指定哪一方是错误的情况下进行外连接。

答案 2 :(得分:0)

作为一般设计建议,我会说这个模式缺少正确的主键 - 每个表都应该有一个数字id列,因为依靠名称等实际值的唯一性或不变性是不明智的。

然后应该打破功能,因为这段代码在一个地方做得太多了。查找一个玩家名称的id可能应该是一个不同的函数,如果没有找到玩家则可以返回null,或者可以引发错误(就像将一个空玩家名称传递给该函数一样)。

我会将“查找播放器”功能分解为另一个功能,如果播放器名称不存在,则只返回null而不是播放器ID。

返回最喜欢的体育场馆的数量应该是返回0或更大的整数,而不需要魔术数字来表示其他条件。