2013-05-31 75 views
2

我正在嘗試編寫一個PL/SQL函數,該函數以玩家的名字作爲參數,並返回在他最喜歡的場館中玩的比賽數量。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

我不確定這個ERD是否比聲明更容易閱讀。 –

+0

您編輯的查詢語法錯誤。你需要'SELECT value1,value2 INTO variable1,variable2 FROM ...' –

回答

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; 
+0

爲什麼我不能使用count()而不是sum()? – Martin

+0

哇,我在想什麼!夥計,如果(count(...))???你究竟在計算什麼?那裏沒有選擇語句,它只是一個if語句... :) – Ted

+0

謝謝。上面那部分你解釋'如果players.name爲空然後...'是錯誤的。你能告訴我一個代碼示例嗎?我很難理解我會如何做到這一點。 – Martin

0

我認爲這是你的加入有不正確的語法。試試:INNER JOIN和LEFT OUTER JOIN。這樣做和外部聯接沒有指定哪一邊是錯誤的。

+2

連接非常好。 「外部連接」是一個「完全外部連接」,不需要「邊」。 –

+0

使用你的建議,它確實消除了上面的原始2錯誤。我現在只有'如果players.name爲空然後'行錯誤。我收到錯誤:'PLS-00357:表,視圖或序列引用'PLAYERS.NAME'在此上下文中不允許'。有任何想法嗎?謝謝 – Martin

+0

在你的圖表中,表名是PLAYER而不是PLAYERS。其他問題是,您在查詢中沒有使用輸入變量pname,因此您使用完整外連接查詢所有玩家。另外我不認爲你的條件會起作用,我想你的查詢中需要這樣的邏輯(見Ted的答案)。 –

0

作爲一般的設計建議,我會說這個模式缺少正確的主鍵 - 每個表都應該有一個數字ID列,因爲依靠真實值(如名稱)的唯一性或不可變性是不明智的。

然後應該打破功能,因爲這個代碼在一個地方做得太多。查找播放器名稱的ID可能應該在不同的函數中,如果沒有找到播放器,則可以返回null,或者可能會引發錯誤(就像可能會將null播放器名稱傳遞給函數一樣)。

我會打出來的「查找播放器」功能到另一個功能,如果玩家名稱不存在,那麼就返回玩家ID的空代替。

回到最喜歡的體育場館的數量,然後應該是返回一個整數,大於或等於0,且不需要幻數來表示的其他條件的問題。