假设我有一个包含 mySpec.pks
中定义的规范的软件包CREATE OR REPLACE PACKAGE TEST_PKG AS
PROCEDURE TEST_1 ( asdf int );
PROCEDURE TEST_2 ( asdf int, asdf2 char );
END;
是否可以将每个过程的实现拆分为多个主体“CREATE OR REPLACE PACKAGE BODY”语句? 我正在为身体文件想象这样的东西:
test1.pkb (仅执行程序* TEST_1 *)
CREATE OR REPLACE PACKAGE BODY TEST_PKG AS
PROCEDURE TEST_1 ( asdf int ) IS
BEGIN
--do stuff
END;
END;
test2.pkb (仅执行程序* TEST_2 *)
CREATE OR REPLACE PACKAGE BODY TEST_PKG AS
PROCEDURE TEST_2 ( asdf int, asdf2 char ) IS
BEGIN
--do stuff
END;
END;
答案 0 :(得分:7)
不,不是。包体是单个实体,必须有一个CREATE
语句。就像对象的整个实现必须在一个文件中一样,包的整个实现必须在一个文件中。
将实现分成多个文件的愿望往往意味着我认为软件包本身正在尝试做太多,并且需要将整个软件包重构为两个或更多更小,更自包含的软件包。 / p>
答案 1 :(得分:5)
您不能完全按照您的建议进行操作,但只要您使用SQL * Plus加载包,就可以将包体文件拆分为更小的部分。我并不是说这是一个好主意,如果你因为尺寸原因这样做,我通常会同意Justin重构你的设计。但仅仅因为你可以:
在脚本中定义包体,为每个过程说出test_pkg.pkb
和'include'子文件:
CREATE OR REPLACE PACKAGE BODY TEST_PKG AS
@test_1.sql
@test_2.sql
END TEST_PKG;
/
然后在test_1.sql
:
PROCEDURE TEST_1 ( asdf int ) IS
BEGIN
--do stuff
END TEST_1;
在test_2.sql
:
PROCEDURE TEST_2 ( asdf int, asdf2 char ) IS
BEGIN
--do stuff
END TEST_2;
执行脚本时,解析器仍将其视为单个create
语句。
你不能单独运行'included'文件,它们只能作为包体载荷的一部分 - sqlplus @test_pkg.pkb
- 所以如果你的目标是只允许一个程序重新加载这个赢了不行。
还有另一个缺点,因为任何编译错误消息都会引用整个包体中的行号,因此您必须确定相关代码所在的子文件中的哪个,这是可行的但是有点棘手。同样,user_source
中存储的内容与文件中的内容不匹配。这有点像看我预测的预处理的C或Pro * C文件,相关但并不总是很容易与原始文件协调。
所以......可能不值得努力和混淆的可能性。
答案 2 :(得分:1)
每个包规范对应于一个且仅包含一个包体。
如果您愿意,可以创建2个包规格和2个包体以分隔这些功能。
规范有一个目的并且做了很多事情,比如使某些过程/函数可以被其他包/ proc / func调用,声明包全局变量,指定诸如“authid current_user”之类的东西......
Oracle已经仔细考虑了pl / sql:)