调用同时使用一个变量而不具有变量的重载存储过程



我的重载过程代码中有几个示例,但仅取一组,以下是我拥有的两个日志记录过程:

  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;

这个想法是,这两个过程都可以从异常块中调用。根据是否提供了参数,将调用另一个过程,并出现预期错误(如采用参数的过程)或其他 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;

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

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

无论如何,至少这是理论。

我似乎无法让它工作。当我尝试编译程序时,我被告知:

PLS-00307: too many declarations of LOG_AND_RETURN match this call.

我在代码中使用的每个实例都得到了这个。这是为什么呢?我假设它与不传递参数的过程有关(它是否可能传递NULL或类似的东西?我已经尝试删除无输入参数过程,以查看是否正在传递值(如NULL),但这没有任何作用。我做错了什么?

这是因为

IN VARCHAR2 := NULL声明;您为参数提供默认值,使其成为可选值。当你有一个像ERR.Log_And_Return;这样的调用时,你可以调用你的第一个版本,它不接受参数,或者调用你的第二个版本,有一个参数,但让它选择默认值。编译器无法分辨出你的意思。

无论如何,在这种情况下,

看起来你并不真正想要默认值;你总是会传递一些东西,即使参数本身是空的,所以默认并没有真正给你带来任何东西。如果你真的没有争论地调用它,那么你无论如何都会想要第一个"当其他人"版本。

因此,只需将过程规范和声明更改为:

  PROCEDURE Log_And_Return(
    in_err_name   IN    VARCHAR2
  );

。没有默认设置。

SQL 小提琴,默认

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

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

这在PL/SQL语言参考手册中有涉及;尽管在您的示例中,您无法使用不同命名的形式参数来解决它,因为一个版本根本没有任何参数。

最新更新