2013-05-13 118 views
0

下面的函數應該返回與特定會議的信息,存儲在會議桌上:甲骨文:函數只返回null

CREATE TABLE "MEETING" 
    ( "MEETING_ID" NUMBER(10,0) NOT NULL ENABLE, 
    "TIME" TIMESTAMP (4) NOT NULL ENABLE, 
    "LOCATION" VARCHAR2(40), 
    "MAP_HREF" VARCHAR2(140), 
    "FK_INTEREST_ID" CHAR(4) NOT NULL ENABLE, 
    "ADDITIONAL_INFO" CLOB, 
    "PASSED" NUMBER(1,0), 
    "TITLE" VARCHAR2(20), 
    CONSTRAINT "MEETING_PK" PRIMARY KEY ("MEETING_ID") ENABLE 
    ) ; 

代碼編譯就好了,和精美的運行以及。

但是,如果會議存在,則只返回null。如果會議不存在,則正確打印「UNKNOWN APPOINTMENT」。

CREATE OR REPLACE FUNCTION GetMeeting 
        (meetingnumber MEETING.MEETING_ID%TYPE) 
RETURN VARCHAR 
IS 
    CURSOR current_meeting(meetingnumber MEETING.MEETING_ID%TYPE) 
    IS 
     SELECT TITLE 
     FROM MEETING 
     WHERE MEETING_ID = meetingnumber; 

    r_meeting current_meeting%ROWTYPE; 
BEGIN 
    OPEN current_meeting(meetingnumber); 

    FETCH current_meeting INTO r_meeting; 

    IF current_meeting%NOTFOUND THEN 
     r_meeting.TITLE := 'UNKNOWN APPOINTMENT'; 
    END IF; 

    CLOSE current_meeting; 

    RETURN r_meeting.TITLE; 
END; 


SELECT GetMeeting (27) appointment 
FROM MEETING; 
+0

TITLE不是強制性列。你確定你已經填入ID = 27的記錄嗎? – APC 2013-05-13 13:02:38

回答

2

似乎這是使用遊標的練習?它比它需要的複雜得多。試着這麼做(未經測試):

create or replace function get_meeting(i_meetingnumber MEETING.MEETING_ID%TYPE) 
RETURN VARCHAR2 
IS 
    l_title MEETING.TITLE%TYPE; 
BEGIN 

    select title 
    into l_title 
    FROM MEETING 
    WHERE MEETING_ID = i_meetingnumber; 

    return l_title; 
EXCEPTION 
    when no_data_found then 
    return 'UNKNOWN APPOINTMENT'; 
    when others then raise; 
END; 

這也有點沒有必要把這個小邏輯函數,我會簡單地選擇它作爲需要(通過一個一個加入一個更大的SQL或單獨更大的PL/SQL程序)

另外,我注意到你的原始函數返回VARCHAR,其中標題是VARCHAR2。不確定如果轉換是由Oracle隱式完成的,但值得一提的是。

0

檢查下面的語句:

IF r_meeting%NOTFOUND THEN 
     r_meeting.TITLE := 'UNKNOWN APPOINTMENT'; 
     END IF; 

     CLOSE current_meeting; 

     RETURN r_meeting.TITLE; 
    END; 
0

PL/SQL函數工作正常。它返回所需的結果,但您的選擇會返回與MEETING中一樣多的數據集。您應該從雙重選擇。

+1

咦?遊標具有MEETING_ID的WHERE子句,所以如果MEETING_ID重複(由於主鍵約束而不可能),它將只返回多行。 – 2013-05-13 13:24:38

+1

@Frank我沒有談到函數內部的選擇。我的意思是最後選擇(SELECT GetMeeting(27)約會FROM MEETING;) – 2013-05-13 13:27:52

+0

(自我糾正)我假設你正在談論第二次選擇(SELECT GetMeeting(27)約會從會議)。當然,你對這個問題是正確的 - 從DUAL那裏會更有意義。 – 2013-05-13 13:28:03

1
SELECT NVL(TITLE, 'UNKNOWN APPOINTMENT') FROM MEETING WHERE MEETING_ID = meetingnumber; 

更清潔。

+1

這不是PL/SQL。你不能只選擇。一旦你對PL/SQL變得友好,通過選擇INTO的東西,很明顯爲什麼這種方法不起作用。 – 2013-05-13 22:30:08

+0

你的評論讓我感到很開心。但是,由於您提供的材料沒有爲智力活動留下太多空間,因此我請您進一步闡述。我會補充一點,我的回答是一個建議,並且根據問題的實際數據而不是猜測任何事情,它代表了一個好的和便宜的解決方案。請注意,我感謝您對我對PL/SQL的友好關注。 – Sebas 2013-05-13 23:04:31

+0

你的答案不會在任何PL/SQL塊中編譯。因此它不是PL/SQL。它是SQL。如果您將SQL重新編譯爲可以編譯的內容,例如將其更改爲:'SELECT NVL(TITLE,'UNKNOWN APPOINTMENT')INTO a_plsql_variable FROM MEETING WHERE MEETING_ID = meetingnumber;'然後您會看到當集合,行數)是空的(即,沒有行,no_data_found,但是你想看看它),那麼你的NVL()函數沒有預期的效果。 – 2013-05-14 02:06:09