我在包中创建了一个返回 NUMBER 类型的函数,但没有在包规范中声明此函数。
我在 SQL 查询的另一个函数中调用这个函数,它在同一个包体中。我收到错误。
当我在包规范中声明函数时,它可以正常工作。
我想知道背后的原因。请任何人解释一下。
我在包中创建了一个返回 NUMBER 类型的函数,但没有在包规范中声明此函数。
我在 SQL 查询的另一个函数中调用这个函数,它在同一个包体中。我收到错误。
当我在包规范中声明函数时,它可以正常工作。
我想知道背后的原因。请任何人解释一下。
与前向声明完全无关。
这涉及您使用 SQL 查询来调用函数的事实。似乎当使用语句调用函数时,您不再处于 PL/SQL 包的范围内,因此您只能调用公开可用的函数。
至于为什么,我只能猜测,所以不要想当然,但是PL/SQL和SQL有不同的引擎。因此,在执行 sql 查询时,即使在您的 pl/sql 包中,您也会转到 SQL 级别,它将根据 SQL 引擎再次检查权限。所以它不知道它是从一个 PL/SQL 包中执行的,你应该被允许调用私有函数。
我认为可以轻松检查引擎的差异,尝试使用 32000 的 varchar2,它将在您的 pl/sql 函数中工作。现在,如果您调用返回 a 的 pl/sql 函数varchar2(32000)
,它将失败。这是我遇到的一个问题,但我没有任何数据库可以给你一个片段。
您可以使用仅在包体中声明的函数,但您必须在首次使用它们之前声明它们:
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
/
是的,这称为前向声明。如果任何程序/函数未在包 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
/