我创建了一个检查表的函数。
如果学生存在,请返回Y。
我遇到运行时错误。
create or replace FUNCTION ssc_f_get_speical_need (P_STUDENT_NO IN NUMBER )
RETURN char
IS
l_exist number ;
begin
select s.STUDENT_NO
into l_exist
from SSC_WITH_SPECIAL_NEED s
where s.STUDENT_NO = P_STUDENT_NO ;
if (l_exist = P_STUDENT_NO) then
return 'Y' ;
else
return 'N' ;
end if;
end;
答案 0 :(得分:1)
由于STUDENT_ID很可能是主键列,因此不允许重复,因此SELECT
无法返回TOO_MANY_ROWS
。另一方面,如果参数P_STUDENT_ID包含表中不存在的值,则可能返回NO_DATA_FOUND
。
修复它的一种简单方法是使用聚合函数(例如我的示例中的MAX
)将返回
NO_DATA_FOUND
,因此您不必编写异常处理程序出于测试目的,我基于Scott的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提升其他所有东西(如有必要,稍后再处理)。
答案 1 :(得分:0)
如果您想避免NO_DATA_FOUND
或TOO_MANY_ROWS
例外,那么您可以将查询重写为类似于以下内容的内容:
select decode(count(s.STUDENT_NO),0,'N','Y')
into l_result
from SSC_WITH_SPECIAL_NEED s
where s.STUDENT_NO = P_STUDENT_NO ;
因此,您的功能将如下所示:
create or replace function ssc_f_get_speical_need(p_student_no in number )
return char
is
l_result varchar2(1) ;
begin
select decode(count(s.student_no),0,'N','Y')
into l_result
from ssc_with_special_need s
where s.student_no = p_student_no ;
return l_result;
end;
答案 2 :(得分:0)
您可能会收到错误,例如&#34;未找到任何数据&#34;如果没有学生的学生编号。 如果至少有一个匹配的行,请尝试检查您的表格。
CREATE OR REPLACE FUNCTION ssc_f_get_speical_need (p_student_no IN NUMBER)
RETURN CHAR
IS
l_exist NUMBER;
l_count NUMBER;
BEGIN
SELECT COUNT ( * )
INTO l_count
FROM ssc_with_special_need s
WHERE s.student_no = p_student_no;
IF l_count > 0
THEN
SELECT s.student_no
INTO l_exist
FROM ssc_with_special_need s
WHERE s.student_no = p_student_no;
IF l_exist = p_student_no
THEN
RETURN 'Y';
END IF;
END IF;
RETURN 'N';
END;
答案 3 :(得分:0)
在你的函数中添加一个异常,只是为了测试,如果错误仍然存在,那么问题出在另一个地方。
CREATE OR REPLACE FUNCTION....
BEGIN....
EXCEPTION WHEN OTHERS THEN --catch any error
RETURN 'E';
END
https://www.techonthenet.com/oracle/exceptions/when_others.php
答案 4 :(得分:0)
无论是否使用主键,对存在进行测试,我总是遵循Tom Kyte的模式从双重存在中进行选择。
create or replace function ssc_f_get_special_need
(p_student_no in number)
return char
is
l_exist pls_integer;
begin
select count(*)
into l_exist
from dual
where exists
(select s.student_no
from ssc_with_special_need s
where s.student_no = p_student_no);
return case when l_exist = 1 then 'Y' else 'N' end;
end;
/