3
CREATE OR REPLACE FUNCTION get_status_by_member_id
(p_member_id NUMBER) 
RETURN CHAR
AS
  v_status CHAR(1);
BEGIN
  select status
  into v_status
  from members
  where member_id = p_member_id;
  if v_status is null then
    return v_status || 'N';
  else
     return v_status;
  end if;
END get_status_by_member_id;
4

2 に答える 2

6

あなたの問題は、時々迷惑な Oracle の癖によって引き起こされます。つまり、PL/SQL 関数が SQL で呼び出され、エラーnullが返された場合は、他のものではなく返されます。

非常に単純なテーブルを作成すると...

create table a ( b number, c varchar2(1) );
insert into a values (1,'Y');

...そして2つの機能。例外処理のないもの

create or replace function tmp_ben_fn (PId number) return char is
   l_status varchar2(1);   
begin  

   select c
     into l_status
     from a
    where b = PId;

   return coalesce(l_status, 'N');

end;
/

もう 1 つは例外処理付きです。

create or replace function tmp_ben_fn2 (PId number) return char is
   l_status varchar2(1);   
begin  

   select c
     into l_status
     from a
    where b = PId;

   return coalesce(l_status, 'N');

   exception when no_data_found then
      return 'A';

end;
/

次に、これら 2 つの関数を使用してデータを選択します。Y行が 1 つしかないので、 orのみNが返されることを期待していることを思い出してください。

SQL> -- Expected output Y
SQL> select tmp_ben_fn(1) from dual;

TMP_BEN_FN2(1)
-------------------------------------------------

Y

SQL> -- Expected output, Error no_data_found
SQL> -- as row 2 does not exist.
SQL> select tmp_ben_fn(2) from dual;

TMP_BEN_FN(2)
-------------------------------------------------



SQL> -- Expected output, the same as tmp_ben_fn
SQL> select tmp_ben_fn2(2) from dual;

TMP_BEN_FN2(2)
-------------------------------------------------

A

SQL>

エラー処理のない関数でわかるように、no_data_found例外が発生すると anullが返されます。例外をキャプチャすると、A代わりに期待どおりの結果が得られます。

member_id選択しようとしている は存在しないと思われます。

原則として、例外が発生する可能性がある場合は常に注意してください。これは、select into...選択する行が多すぎる場合と行が選択されない場合の特に厄介な例です。テーブルが一意であるmember_id場合は、関数を次のように変更する必要があります。

CREATE OR REPLACE FUNCTION get_status_by_member_id (p_member_id NUMBER) 
RETURN CHAR IS
  v_status CHAR(1);
BEGIN
  select status
  into v_status
  from members
  where member_id = p_member_id;

  return v_status;

-- If the member_id does not exist
-- return N
exception when no_data_found then
   return 'N';
END get_status_by_member_id;
于 2012-08-14T17:07:05.130 に答える
2

次のように、コードに例外ハンドラーを追加してみてください。

CREATE OR REPLACE FUNCTION get_status_by_member_id 
  (p_member_id NUMBER) RETURN CHAR 
as 
  v_status CHAR(1); 
begin 
  BEGIN
    select status 
      into v_status 
      from members 
      where member_id = p_member_id;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      v_status := NULL;
    WHEN TOO_MANY_ROWS THEN
      v_status := NULL;
  END;

  if v_status is null then 
    return 'N'; 
  else 
    return v_status; 
  end if; 
end get_status_by_member_id; 

これは、p_member_idに一致するデータがない場合、またはp_member_idに一致する複数の行がある場合を処理します。これにより、発生している問題が修正される場合と修正されない場合があります。投稿を編集して、使用しているコードを追加すると便利ですget_status_by_member_id

共有してお楽しみください。

于 2012-08-14T16:46:10.313 に答える