2016-08-20 1582 views
2

在Oracle 12.1中,我有一个相当简单的PL/SQL例程。输出是单个值,可以是逗号分隔的名称列表或字符串“NO_DATA”。没有其他输出允许。对于输入,有一个单一的值,一个公司名称。如果我硬编码公司名称,并从SQL窗口运行SQL语句(不是函数),它运行良好,所以我知道SQL是有效的。这个问题与异常处理有关。如果我没有任何异常处理,并传递一个有效的名称给函数,它会给我一个有效的输出。当我找不到数据时,我需要能够处理这种情况,所以我添加了简单的异常处理。这是我得到我的问题的地方。有了异常处理代码,如果我传入了一个不合适的值(又名公司名称,未找到),我就会像'我应该'那样得到'NO_DATA'。如果我传递了一个很好的值,那么我得到一个PL/SQL错误ORA-06503:PL/SQL:函数返回时没有值。这是我的代码。PL/SQL异常处理 - 函数无返回值返回

create or replace FUNCTION authorized_email(nn1 in varchar2) 
    RETURN varchar2 
    IS 
    thisName varchar2(4000); 
    Output varchar2(4000); 

-- this routine build the list of comma seperated authorized users 

BEGIN 

SELECT NN_Name,  
     nvl(replace(Upper(LISTAGG(Name, ',') WITHIN GROUP (ORDER BY Name)), '@XYZ.COM', NULL), 'NO_DATA') AS Names 
     into thisName, Output 
FROM (
    SELECT DISTINCT(NN_NAME), 
     Name 
    FROM LINE_ITEMS 
    UNPIVOT(name FOR typ IN ( 
     FMW_MGR_L3_EMAIL, 
     FMW_MGR_L4_EMAIL, 
     FMW_MGR_L5_EMAIL, 
     FMW_MGR_L6_EMAIL, 
     FMW_MGR_L7_EMAIL, 
     FMW_EMAIL, 
     HYBRID_MGR_L3_EMAIL, 
     HYBRID_MGR_L4_EMAIL, 
     HYBRID_MGR_L5_EMAIL, 
     HYBRID_MGR_L6_EMAIL, 
     HYBRID_MGR_L7_EMAIL, 
     HYBRID_REP, 
     TECH_MGR_L3_EMAIL, 
     TECH_MGR_L4_EMAIL, 
     TECH_MGR_L5_EMAIL, 
     TECH_MGR_L6_EMAIL, 
     TECH_MGR_L7_EMAIL, 
     TECH_EMAIL) 
    )) 
where NN_NAME = nn1 
GROUP BY NN_NAME; 

EXCEPTION 
    WHEN no_data_found then  
    Output := 'NO_DATA'; 

return Output; 


END; 

我的EXCEPTION HANDLING代码有问题,但我无法确定它是什么。任何帮助感谢!

回答

2

在发生异常之前,您不会返回任何值。

那么你应该低于EXCEPTION

Output := 'NO_DATA'; 
return Output; 

添加

return Output; 

的陈述时,NO_DATA_FOUND触发只执行。

所以,你的代码应该像

BEGIN 
     SELECT NN_Name,  
       nvl(replace(Upper(LISTAGG(Name, ',') WITHIN GROUP (ORDER BY Name)), '@XYZ.COM', NULL), 'NO_DATA') AS Names 
       into thisName, Output 
     FROM (
      --skipped) 
      )) 
     where NN_NAME = nn1 
     GROUP BY NN_NAME; 
     return Output; --  <--- code added 
    EXCEPTION 
     WHEN no_data_found then  
     Output := 'NO_DATA'; 
     return Output; 
    END; 
+0

所以,你还需要'返回输出;'了'EXCEPTION'块之前。 – mathguy

+0

那是我的罪魁祸首。谢谢! – user1009073

4

你的困惑是在这里:

EXCEPTION 
    WHEN no_data_found then  
    Output := 'NO_DATA'; 

return Output; 

WHEN条款不会终止,直到它击中另一WHEN或与END。所以你的return Output;是异常处理程序的一部分,不是代码主体的一部分。 (你缩进代码的方式可能会产生这样的印象,即return语句在异常处理程序之外,但编译器并不在意这一点,只是关于定义的语法。)

我会建议稍微不同修复比在其他答案,以避免有多个返回语句。您可以嵌套BEGIN/END块来完成你想要的流量:

BEGIN 
    BEGIN 
    ... SQL statement here... 
    EXCEPTION 
    WHEN no_data_found then  
     Output := 'NO_DATA'; 
    END; 

    return Output; 
END;