Поскольку STUDENT_ID, скорее всего, является столбцом первичного ключа, он не допускает дублирования, поэтому SELECT
не может вернуть TOO_MANY_ROWS
. С другой стороны, он может вернуть NO_DATA_FOUND
, если параметр P_STUDENT_ID содержит значение, которого нет в таблице.
Простой способ исправить это - использовать агрегатную функцию (например, MAX
в моем примере), которая будет возвращать
- значение, если оно существует
- NULL, если нет
- но не вернет
NO_DATA_FOUND
, поэтому вам не нужно кодировать обработчик исключений
В целях тестирования я создал таблицу dummy на основе таблицы EMP Скотта.
create table ssc_with_special_need as
select empno student_no from emp
where rownum < 5;
Теперь функция:
create or replace function ssc_f_get_special_need
(p_student_no in number)
return char
is
l_exist ssc_with_special_need.student_no%type;
begin
select max(s.student_no)
into l_exist
from ssc_with_special_need s
where s.student_no = p_student_no;
return case when l_exist is not null then 'Y'
else 'N'
end;
end;
/
Тестирование:
SQL> select * from ssc_with_special_need;
STUDENT_NO
----------
7369
7499
7521
7566
SQL> select ssc_f_get_special_need(1) result_1, --> doesn't exist in the table (return N)
2 ssc_f_get_special_need(7369) result_2 --> exists in the table (return Y)
3 from dual;
RESULT_1 RESULT_2
---------- ----------
N Y
SQL>
Лучшим (правильным) способом является обработка возможных исключений; как я уже сказал, я не буду обрабатывать TOO_MANY_ROWS
, так как его не следует поднимать, если STUDENT_ID является столбцом первичного ключа.
create or replace function ssc_f_get_special_need
(p_student_no in number)
return char
is
l_exist ssc_with_special_need.student_no%type;
begin
select s.student_no
into l_exist
from ssc_with_special_need s
where s.student_no = p_student_no;
-- if the above SELECT returned a value, return 'Y' immediately
return 'Y';
exception
when no_data_found then
-- SELECT didn't find a value and raised an exception - return 'N'
return 'N';
end;
/
Тестирование: результат точно такой же:
SQL> select ssc_f_get_special_need(1) result_1,
2 ssc_f_get_special_need(7369) result_2
3 from dual;
RESULT_1 RESULT_2
---------- ----------
N Y
SQL>
Я бы не стал использовать WHEN OTHERS
, так как это, вообще говоря, вредная привычка: обрабатывать то, что вы ожидаете, позвольте Oracle поднять все остальное (и обработать это позже, если необходимо).