在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代码有问题,但我无法确定它是什么。任何帮助表示赞赏!
答案 0 :(得分:4)
你的困惑在这里:
EXCEPTION
WHEN no_data_found then
Output := 'NO_DATA';
return Output;
WHEN
子句在到达另一个WHEN
或END
之前不会终止。所以你的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;