0

次の関数は、会議テーブルに格納されている特定の会議に関する情報を返すことになっています。

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

4 に答える 4

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によって暗黙的に行われるかどうかはわかりませんが、言及する価値があります。

于 2013-05-13T13:39:16.930 に答える
1
SELECT NVL(TITLE, 'UNKNOWN APPOINTMENT') FROM MEETING WHERE MEETING_ID = meetingnumber;

はるかにきれいです。

于 2013-05-13T13:45:47.090 に答える
0

以下のステートメントを確認してください。

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

        CLOSE current_meeting;

        RETURN r_meeting.TITLE;
    END;
于 2013-05-13T12:56:52.683 に答える
0

PL/SQL 関数は正常に動作します。目的の結果が返されますが、選択すると、MEETING に存在するのと同じ数のデータセットが返されます。代わりにデュアルから選択する必要があります。

于 2013-05-13T13:01:07.043 に答える