2

プレーヤーの名前をパラメーターとして受け取り、お気に入りのスタジアムで行われた試合の数を返す 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

これを修正する方法についてのアイデアはありますか?

これが役立つ場合のデータベースの関係図は次のとおりです。

ここに画像の説明を入力

編集(テッド用):

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;
4

3 に答える 3

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;

も間違っています。select ステートメントもありません。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;
于 2013-05-31T09:29:24.347 に答える
0

一般的な設計上のアドバイスとして、このスキーマには適切な主キーがありません。名前などの実際の値の一意性や不変性に依存するのは賢明ではないため、各テーブルには数値の id 列が必要です。

次に、このコードは 1 つの場所で多くのことを行っているため、機能を分割する必要があります。プレイヤー名の ID を検索することは、おそらく別の関数で行うべきであり、プレイヤーが見つからない場合は null を返すか、エラーが発生する可能性があります (null プレイヤー名が関数に渡された場合と同様)。

「プレーヤーの検索」機能を別の関数に分割し、プレーヤー名が存在しない場合は、プレーヤー ID の代わりに null を返します。

お気に入りのスタジアムの数を返すには、0 以上の整数を返すだけでよく、他の条件を示すマジック ナンバーは必要ありません。

于 2013-05-31T09:46:09.567 に答える