我有运行时错误任何身体可以检查功能和缺少什么

时间:2018-04-26 13:03:03

标签: oracle plsql oracle-apex plsqldeveloper

我创建了一个检查表的函数。

如果学生存在,请返回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;

5 个答案:

答案 0 :(得分:1)

由于STUDENT_ID很可能是主键列,因此不允许重复,因此SELECT无法返回TOO_MANY_ROWS。另一方面,如果参数P_STUDENT_ID包含表中不存在的值,则可能返回NO_DATA_FOUND

修复它的一种简单方法是使用聚合函数(例如我的示例中的MAX)将返回

  • 值(如果存在)
  • 如果不是
  • ,则为NULL
  • 但不会返回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_FOUNDTOO_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;
/