Форвардная декларация в упаковке - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть вопрос, и я не могу найти ответ от Google.Это может быть простой вопрос, так как я новичок, у меня есть это сомнение.

Можем ли мы объявить функцию в спецификации пакета и использовать ту же функцию для прямого объявления?

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 голосов
/ 11 декабря 2018

Вы не можете (вперед) объявлять функцию в теле, потому что она уже была объявлена ​​в спецификации.

Это просто проверить с очень незначительным заполнением вашего псевдокода:

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 только для частных подпрограмм?

Да.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...