oracle - 在PL/SQL中引发错误后返回函数的最佳实践吗

标签 oracle plsql

我在程序包中有一堆函数,这些函数首先检查所请求工作的有效性,如果没有,则抛出异常。

例子:

package body foo as
  function implode (
    i_foo_id number
  ) return implode_id as
    not_implodable exception;
    implode_id number;
  begin
    if not is_implodable(i_foo_id) then
      raise not_implodable;
    end if;
    //Implode logic here.
    return implode_id;
  exception
    when not_implodable then
      raise_application_error(-20005, 'Imploding is not possible on this foo.');
  end implode;
end foo;

我已打开警告报告,并在编译时得到了类似的信息。

警告(67,3):PLW-05005:子程序IMPLODE在第14行返回无值。

如果我在raise_application_error之后放置return语句,则警告消失。由于引发错误会退出调用堆栈,因此是否有充分的理由要返回null?

最佳答案

否。不是,这是在PL/SQL中引发并出错后返回函数的最佳实践。

有时甚至建议添加代码只是为了关闭编译器,例如:

exception
  when fooex then
    raise_application_error(-20100, 'invalid number');
    return null; -- silence PLW-05005
end;

请务必记录这样一个特殊的代码!

通常,我不喜欢这样的代码来满足编译器警告,但是该规则始终存在异常(exception)。在这种特殊情况下,我想说的是问题更多是编译器而不是代码。在我看来,如下所示的代码是完全有效的,编译器不应对此提示。实际上,我认为编译器应该警告块是否在raise之后包含语句,因为它实际上是无效代码(无法访问的代码)。

让我们考虑以下函数:
$ cat foo.sql 
create or replace function foo(p_in in number)
return number is
  fooex exception;
begin
  if p_in < 1 then
    raise fooex;
  end if;

  return p_in;
exception
  when fooex then
    raise_application_error(-20100, 'invalid number');
end;
/
show errors

在Oracle 11g XE中运行此命令:
-- By default the warnings are disabled
SQL> @foo

Function created.

No errors.

通常我想要所有警告:
SQL> alter session set plsql_warnings = 'ENABLE:ALL';

Session altered.

SQL> @foo

SP2-0806: Function created with compilation warnings

Errors for FUNCTION FOO:

LINE/COL ERROR
-------- -----------------------------------------------------------------
1/1      PLW-05005: subprogram FOO returns without value at line 13
1/1      PLW-05018: unit FOO omitted optional AUTHID clause; default
         value DEFINER used

在检查了代码之后,我发现上面的警告是不正确的,因此我仅针对此编译单元禁用它们:
SQL> alter session set plsql_warnings = 'ENABLE:ALL, DISABLE:(5005,5018)';

Session altered.

SQL> @foo

Function created.

No errors.
SQL>

现在一切都好极了。

我的建议是默认情况下打开所有警告,然后关闭每个编译单元(alter session set plsql_warnings = 'ENABLE:ALL, DISABLE:(5005,5018)';)的错误肯定信息。如果可能的话:alter system plsql_warnings = 'ENABLE:ALL';,但实际上这可能有点太苛刻了...

哦,建议您打开所有编译器错误检查。作为程序员,我们需要编译器可以提供给我们的所有帮助!不幸的是,对于Oracle PL/SQL编译器,这需要妥协。

关于oracle - 在PL/SQL中引发错误后返回函数的最佳实践吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22234004/

相关文章:

sql - ORA-00036 : maximum number of recursive SQL levels (50) exceeded after configuring toplink to use bind variables

java - 无法存储作业 : Driver's Blob representation is of an unsupported type: oracle. sql.BLOB [请参阅嵌套异常 : java. sql.SQLException

mysql - 数据库开发 - 总体结构和规划

java.sql.SQLSyntaxErrorException : ORA-01729: database link name expected while using Java stored procedure

oracle - 在存储过程中使用 EXECUTE IMMEDIATE 执行 DML 语句

oracle - 创建 Oracle 过程

c# - c#中的一些数字、日期和电话号码使用什么数据类型?

java - PLS-00103 : Encountered the symbol "end-of-file" in FlyWay

oracle - 绑定(bind)变量和替换变量(我使用 && 输入)有什么区别?

plsql - 正在使用以下函数解密代码吗?有什么可以帮助解决的吗?