使用一个变量和无变量调用重载的存储过程

And*_*tin 3 oracle stored-procedures overloading

我在我的重载过程代码中有一些例子,但是只需要一组,这里有两个日志记录程序:

  PROCEDURE Log_And_Return
  IS
  BEGIN
    Handle ('when others', TRUE, FALSE);
  END Log_And_Return;

  PROCEDURE Log_And_Return(
    in_err_name   IN    VARCHAR2 := NULL
  )
  IS
  BEGIN
    Handle (in_err_name, TRUE, FALSE);
  END Log_And_Return;
Run Code Online (Sandbox Code Playgroud)

这个想法是可以从异常块调用这两个过程.根据是否提供了参数,将使用预期错误(如采用参数的过程的情况)或其他Oracle错误(如没有输入的过程的情况)调用另一个过程.

为了进一步解释我的意思,我在我的PL/SQL中使用这些,如下所示:

BEGIN
  SELECT ID
  INTO   ID
  FROM   IDTable
  WHERE  ID = id_entered_by_user;
EXCEPTION
WHEN NO_DATA_FOUND THEN
  ERR.Log_And_Return (in_err_name => 'id_not-found');
WHEN OTHERS THEN
  ERR.Log_And_Return;
END;
Run Code Online (Sandbox Code Playgroud)

因此,如果使用上面的查找找不到ID,则该过程将执行该NO_DATA_FOUND块.Handle过程最终被调用,并且使用id_not_found参数,它能够在另一个表上执行查找并向调用程序输出适当的错误消息.

如果发生另一个错误(WHEN OTHERS),则Oracle异常将返回给调用程序.

无论如何,至少那是理论.

我似乎无法让它发挥作用.当我尝试编译程序时,我被告知:

PLS-00307: too many declarations of LOG_AND_RETURN match this call.
Run Code Online (Sandbox Code Playgroud)

我为代码中使用的每个实例都得到了这个.为什么是这样?我假设它与传递没有参数的过程有关(它可能传递一个NULL或类似的东西?).我尝试用去除无输入参数的程序,以查看是否值正在反正通过(像NULL),但什么也没做.我究竟做错了什么?

Ale*_*ole 5

这是因为IN VARCHAR2 := NULL宣言; 您为参数提供了默认值,使其成为可选参数.当你有一个调用,就像ERR.Log_And_Return;你可以调用你的第一个版本,不带参数,或调用你的第二个版本有一个参数,但让它选择默认值.编译器无法告诉您的意思.

在这种情况下看起来你实际上并不想要默认值; 你总是传递一些东西,即使参数本身是空的,所以默认并没有真正获得任何东西.如果你真的没有参数调用它,那么无论如何你都想要第一个'当别人'版本.

所以只需将程序规范和声明更改为:

  PROCEDURE Log_And_Return(
    in_err_name   IN    VARCHAR2
  );
Run Code Online (Sandbox Code Playgroud)

...没有默认设置.

SQL小提示默认显示PLS-00307,另一个SQL小提琴没有默认编译成功.

更一般地说,如果您有重载的过程或函数,则必须通过使用不同的数字或类型(或名称,如果您可以使用命名的实际参数调用)来区分非默认参数.

在PL/SQL语言参考手册中有所涉及; 虽然在你的例子中你不能使用不同命名的形式参数绕过它,因为一个版本根本没有任何参数.