2013-03-11 84 views
2

我写下面FUNCTION检查给定reference number是否存在。PL/SQL函数返回无值

FUNCTION find_reference_no(
    p_ref_no IN VARCHAR2) RETURN VARCHAR2 
AS 

    v_ref_no varchar2(50); 

BEGIN 

    select REF_NO into v_ref_no from cash where REF_NO = p_ref_no; 
    EXCEPTION 
    WHEN no_data_found THEN 
    v_ref_no := '#'; 

RETURN v_ref_no;  

END; 

我在AFTER INSERT TRIGGER中调用了这个函数。当我插入数据,Ii'm得到错误的

ORA-06503: PL/SQL: Function returned without value

我该如何解决这个问题?

PS:我没有将数据插入到cash表中。我将数据插入另一个表(假设它是表B),并在它的(表B)AFTER INSERT TRIGGER中调用该函数。

+3

这种在触发器中的查找正是我们应该避免在触发器中做的那种。这是每个插入的隐藏性能,并且会损害应用程序的可伸缩性。 – APC 2013-03-11 09:15:30

+1

而不是用p_前缀你的参数名称,考虑在查询中用参数名称作为参数名称的前缀 - 即。 “where cash.ref_no = find_reference_no.ref_no”。 v_也作为变量的前缀冗余,它也应该是数据类型为cash.ref_no%Type而不是varchar2(50)。 – 2013-03-11 10:08:00

+0

问题不明显的原因是您的代码格式错误 - RETURN语句*看起来像它是函数正常处理的一部分,而它实际上在函数的EXCEPTION块内。为了清楚起见,EXCEPTION关键字应该位于左侧边界,与BEGIN和END相同。 – 2013-03-12 03:33:22

回答

8

所有函数都必须执行RETURN语句。您的函数在其异常块中具有RETURN,因此该语句在正常情况下不会执行。

附加select声明另加begin end块自己exception部分将解决您的问题。所以你的功能可能是这样的:

create or replace function find_reference_no(
    p_ref_no IN VARCHAR2) return varchar2 
AS 
    v_ref_no varchar2(50); 
begin 
    begin 
    select REF_NO 
     into v_ref_no 
     from cash 
     where REF_NO = p_ref_no; 
    exception 
    WHEN no_data_found THEN 
      v_ref_no := '#'; 
    end; 
    return v_ref_no;  
end; 
2

因为如果在表中存在的函数只是返回相同的值作为参数,你能避免尴尬的使用异常处理和重写此为:

function find_reference_no(
     ref_no in varchar2) 
    return varchar2 
    as 
    row_count integer 
    begin 
    select count(*) 
    into row_count 
    from cash 
    where cash.ref_no = find_reference_no.ref_no and 
      rownum  = 1 

    if row_count = 0 
     return '#' 
    else 
     return ref_no 
    end if; 

    end find_reference_no; 

我会返回一个1或0(即row_count的值)来表明记录是否存在。

function find_reference_no(
     ref_no in varchar2) 
    return varchar2 
    as 
    row_count integer 
    begin 
    select count(*) 
    into row_count 
    from cash 
    where cash.ref_no = find_reference_no.ref_no and 
      rownum  = 1 

    return row_count 

    end find_reference_no;