包中的前向声明

时间:2018-12-11 15:25:24

标签: sql oracle plsql

我有一个问题,但找不到谷歌的答案。 这可能是一个简单的问题,因为我是初学者,对此有疑问。

我们可以在Package规范中声明一个函数,并使用相同的函数进行前向声明吗?

CREATE OR REPLACE PACKAGE pckg_test IS
FUNCTION fun_test(ID NUMBER) RETURN NUMBER;
PROCEDURE proc_test (id number);
END pckg_test ;

CREATE OR REPLACE PACKAGE BODY pckg_test IS 
FUNCTION fun_test(ID NUMBER) RETURN NUMBER; --fwd declaration
PROCEDURE proc_test (id number) is 
BEGIN
....
calling fun_test
....
END;
FUNCTION fun_test(ID NUMBER) RETURN NUMBER is
BEGIN
....
END;
END pckg_test;

1 个答案:

答案 0 :(得分:2)

您不能(向前)在主体中声明该函数,因为它已在规范中声明。

这很容易测试,只需很小的伪代码填写即可:

CREATE OR REPLACE PACKAGE pckg_test IS
FUNCTION fun_test(ID NUMBER) RETURN NUMBER;
PROCEDURE proc_test (id number);
END pckg_test ;
/

Package PCKG_TEST compiled

CREATE OR REPLACE PACKAGE BODY pckg_test IS 
FUNCTION fun_test(ID NUMBER) RETURN NUMBER; --fwd declaration
PROCEDURE proc_test (id number) is 
  x number;
BEGIN
  x := fun_test(1);
END;
FUNCTION fun_test(ID NUMBER) RETURN NUMBER is
BEGIN
  return 42;
END;
END pckg_test;
/

Package Body PCKG_TEST compiled

LINE/COL  ERROR
--------- -------------------------------------------------------------
2/1       PLS-00305: previous use of 'FUN_TEST' (at line 2) conflicts with this use
2/1       PL/SQL: Item ignored
2/10      PLS-00328: A subprogram body must be defined for the forward declaration of FUN_TEST.
Errors: check compiler log

PLS-00305是因为您的前向声明与包装规格中的声明相同(名称和数据类型)。

PLS-00328有点误导; fun_test的完整声明似乎已链接到公共规范,并且前向声明(即使它本身抛出错误)也没有匹配的完整声明。

如果仅删除或注释掉前向声明,那么它将成功编译:

CREATE OR REPLACE PACKAGE BODY pckg_test IS 
--FUNCTION fun_test(ID NUMBER) RETURN NUMBER; --fwd declaration
PROCEDURE proc_test (id number) is 
  x number;
BEGIN
  x := fun_test(1);
END;
FUNCTION fun_test(ID NUMBER) RETURN NUMBER is
BEGIN
  return 42;
END;
END pckg_test;
/

Package Body PCKG_TEST compiled

您不需要(也不被允许)在包主体内fun_test的前向声明,因为它是在包规范中公开声明的-公共规范使该功能可在整个包主体中使用。因此,proc_test仍然可以调用fun_test,即使它在主体代码中排在首位。公共规范具有与前向声明相同的作用。

  

这意味着我只能为私有子程序提供fwd声明吗?

是的