我是PL / SQL的新手,我正在编写一个有点复杂的脚本。为了使脚本更清洁,我想创建许多功能。但是我对功能不太熟悉。 一个函数可以有VOID返回类型吗?如果我必须返回,它将如何处理异常处理? 见下文:
EX:
DECLARE
some_variable NUMBER;
FUNCTION myFunc1(pInput IN NUMBER) RETURN NUMBER
IS
BEGIN
-- DO SOMETHING
EXCEPTION
WHEN someException THEN
DBMS_OUTPUT.PUT_LINE('ERROR someException ');
WHEN Others THEN
DBMS_OUTPUT.PUT_LINE('ERROR');
-----------------------------
-- WHERE DO I PUT THE RETURN?
-----------------------------
END;
FUNCTION myFunc2(pInput IN NUMBER) -- CAN IT RETURN NOTH
IS
fun1Return NUMBER;
BEGIN
-- DO SOMETHING
fun1Return := myFunc1(1);
EXCEPTION
WHEN someException THEN
DBMS_OUTPUT.PUT_LINE('ERROR someException ');
WHEN Others THEN
DBMS_OUTPUT.PUT_LINE('ERROR');
END;
BEGIN
--- DO SOMETHING
some_variable := myFunc2(2);
EXCEPTION
WHEN someException THEN
DBMS_OUTPUT.PUT_LINE('ERROR someException ');
WHEN Others THEN
DBMS_OUTPUT.PUT_LINE('ERROR');
END;
答案 0 :(得分:2)
很好地涵盖了in the documentation。
函数必须在异常处理程序之前返回(如果有的话)。但是在你的例子中,你不应该真正捕捉异常,因为你只是压缩错误,并且你假设无论谁调用它都能看到dbms_output
这不是一个安全的假设。如果你没有重新提升(或任何)异常,那么你仍然需要从异常处理程序以及块的主体返回:
FUNCTION myFunc1(pInput IN NUMBER) RETURN NUMBER
IS
BEGIN
-- DO SOMETHING
RETURN 0;
EXCEPTION
WHEN someException THEN
DBMS_OUTPUT.PUT_LINE('ERROR ' || SQLERRM);
-- how do you know where the exception was raised?
RETURN -1;
WHEN Others THEN
DBMS_OUTPUT.PUT_LINE('ERROR');
-- how does the caller know what went wrong?
RETURN -2;
END;
您还隐藏了错误的所有细节,并消除了能够找出实际出错的希望。捕捉when others
特别邪恶,特别是如果你不重新提出异常。如果你真的想要显示你自己的消息,你仍然应该重新提出原始异常,在这种情况下你不会再需要返回:
FUNCTION myFunc1(pInput IN NUMBER) RETURN NUMBER
IS
BEGIN
-- DO SOMETHING
RETURN 0;
EXCEPTION
WHEN someException THEN
DBMS_OUTPUT.PUT_LINE('ERROR ' || SQLERRM);
RAISE;
WHEN Others THEN
DBMS_OUTPUT.PUT_LINE('ERROR');
RAISE;
END;
哪个稍好一些,但您仍然会丢失有关错误堆栈的一些信息。你可能根本不想抓住这些:
FUNCTION myFunc1(pInput IN NUMBER) RETURN NUMBER
IS
BEGIN
-- DO SOMETHING
RETURN 0;
END;
真正捕捉异常的唯一原因是,如果它是你期望的并且可以优雅地处理。其他任何事情 - 尤其是 other
- 几乎总是更好地向左传播调用堆栈。
如果你的功能中有分支,你也可以有多个回报。
FUNCTION myFunc1(pInput IN NUMBER) RETURN NUMBER
IS
BEGIN
IF SOMETHING THEN
RETURN 1;
END IF;
RETURN 0;
END;
正如@couling所说,一个没有回报的功能就是一个程序。再次剥离异常:
PROCEDURE myProc2(pInput IN NUMBER)
IS
fun1Return NUMBER;
BEGIN
-- DO SOMETHING
fun1Return := myFunc1(1);
END;