【问题标题】:Getting error when calling any function in SQL query in a package without declaring function in package specification在包中调用 SQL 查询中的任何函数而不在包规范中声明函数时出现错误
【发布时间】:2013-01-21 10:39:19
【问题描述】:

我在包中创建了一个返回 NUMBER 类型的函数,但没有在包规范中声明此函数。

我在 SQL 查询中调用此函数,并在同一包体中的另一个函数中调用此函数。我收到错误。

当我在包规范中声明函数时,它可以正常工作。

我想知道它背后的原因。请任何人解释一下。

【问题讨论】:

  • 你能展示你的功能吗?
  • 对不起,这个问题并没有显示出太多的研究工作,也不清楚。 -1 为此。

标签: sql oracle plsql user-defined-functions


【解决方案1】:

与前向声明完全无关。

这涉及您使用 SQL 查询调用函数这一事实。好像使用语句调用函数时,你已经不在PL/SQL包的范围内了,只能调用公开可用的函数。

至于为什么,我只能猜测,所以不要想当然,但是PL/SQL和SQL有不同的引擎。因此,在执行 sql 查询时,即使在您的 pl/sql 包中,您也会转到 SQL 级别,它将根据 SQL 引擎再次检查权限。所以它不知道它是从一个 PL/SQL 包中执行的,你应该被允许调用私有函数。

我认为可以轻松检查引擎的差异,尝试使用 32000 的 varchar2,它将在您的 pl/sql 函数中工作。现在,如果您调用返回varchar2(32000) 的pl/sql 函数,它将失败。这是我遇到的一个问题,但我没有任何数据库可以给你一个 sn-p。

【讨论】:

  • 看来我误读了 OP 的问题 - 我认为调用顺序是 SQL -> function2 -> function1,而他/她可能是指 function2 -> SQL -> function1。在这种情况下,您当然是对的。
【解决方案2】:

你可以使用只在包体中声明的函数,但你必须在它们第一次使用之前声明它们:

create or replace package pkg_so is

  function get2 return number;

end pkg_so;
/
create or replace package body pkg_so is

  function get1 return number is
  begin
    return 1;
  end;

  function get2 return number is
  begin
    return get1 + 1;
  end;

end pkg_so;
/
select pkg_so.get2 from dual
/

【讨论】:

    【解决方案3】:

    是的,这称为前向声明。如果任何过程/函数未在包 sepcificarion 中声明。那么它必须先在body中声明,然后才能在body中第一次使用。

    create or replace package pkg_so is
    
      function get2 return number;
    
    end pkg_so;
    /
    create or replace package body pkg_so is
    
      function get1 return number is
      begin
        return 1;
      end;
    
      function get2 return number is
      begin
        return get1 + 1;
      end;
    
    end pkg_so;
    /
    select pkg_so.get2 from dual
    /
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-12
      • 1970-01-01
      相关资源
      最近更新 更多