2013-05-13 85 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