PL / SQL异常处理 - 返回没有值的函数

时间:2016-08-20 14:44:57

标签: oracle plsql exception-handling

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

答案 0 :(得分:4)

你的困惑在这里:

EXCEPTION
  WHEN no_data_found then    
    Output := 'NO_DATA';

return Output;

WHEN子句在到达另一个WHENEND之前不会终止。所以你的return Output;是异常处理程序的一部分,而不是代码主体的一部分。 (您缩减代码的方式可能会让人觉得return语句在异常处理程序之外,但编译器并不关心它,只是关于定义的语法。)

我建议使用与其他答案略有不同的修复,以避免使用多个return语句。您可以嵌套BEGIN / END块来完成所需的流程:

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

  return Output;
END;

答案 1 :(得分:2)

在例外之前,您不会返回任何值。

然后你应该添加

return Output;

EXCEPTION

下方的陈述
Output := 'NO_DATA';
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;