gpt4 book ai didi

Oracle构建顺序和PL/SQL软件包依赖关系

转载 作者:行者123 更新时间:2023-12-04 11:17:20 30 4
gpt4 key购买 nike

我正在尝试建立一个PL/SQL软件包依赖项列表,以便可以帮助我为要在测试服务器上运行的软件包设置一个自动生成脚本。有没有一种方法可以从单个程序包开始(理想情况下是通过名称标识“根”程序包),然后找到所有依赖项以及它们必须以何种顺序编译?
依赖关系已经在我的个人模式中得到了完全解决(因此,至少我有一个起点要开始,但是下一步我要去哪里?)。

(Oracle 10.2)

编辑:

正在使用的构建工具将使用构建顺序,并将按顺序从源代码管理中检索这些文件,然后将它们传递给Oracle进行编译(实际的构建工具本身是用Python或Java编写的,或者两者都不用-我不会有权访问源代码)。基本上,构建工具需要输入一个文件列表,以按照它们必须在其中进行编译的顺序进行编译,并在源代码管理中访问这些文件。如果有的话,一切都会很好地进行。

编辑:

感谢您的整洁脚本。不幸的是,构建过程主要是我无法控制的。该过程基于一个构建工具,该构建工具是由我们要与之集成的产品的供应商构建的,这就是为什么我唯一能提供给构建过程的输入就是按照它们需要被嵌入的顺序列出的文件列表。如果出现编译器错误,则构建工具将失败,我们必须手动提交新构建请求。因此,按照文件应被编译的顺序列出文件很重要。

编辑:

找到了这个:http://www.oracle.com/technology/oramag/code/tips2004/091304.html
给我任何对象的依赖关系。现在,我只需要正确订购即可。如果我可以正常工作,请在此处发布。

编辑:(带有代码!)

我知道,总的来说,这种事情对于Oracle来说不是必需的,但是对于仍然有兴趣的任何人来说……

我整理了一个似乎能够获得构建顺序的小脚本,以使所有软件包都将以正确的顺序构建,并且第一次没有与依赖项有关的错误(相对于pacakges):

declare

type t_dep_list is table of varchar2(40) index by binary_integer;
dep_list t_dep_list;
i number := 1;
cursor c_getObjDepsByNameAndType is
--based on a query found here: http://www.oracle.com/technology/oramag/code/tips2004/091304.html
select lvl, u.object_id, u.object_type, LPAD(' ', lvl) || object_name obj
FROM (SELECT level lvl, object_id
FROM SYS.public_dependency s
START WITH s.object_id = (select object_id
from user_objects
where object_name = UPPER(:OBJECT_NAME)
and object_type = UPPER(:OBJECT_TYPE))
CONNECT BY s.object_id = PRIOR referenced_object_id
GROUP BY level, object_id) tree, user_objects u
WHERE tree.object_id = u.object_id
and u.object_type like 'PACKAGE%' --only look at packages, not interested in other types of objects
ORDER BY lvl desc;

function fn_checkInList(in_name in varchar2) return boolean is
begin
for j in 1 .. dep_list.count loop
if dep_list(j) = in_name then
return true;
end if;
end loop;
return false;
end;



procedure sp_getDeps(in_objID in user_objects.object_id%type, in_name in varchar2) is
cursor c_getObjDepsByID(in_objID in user_objects.object_id%type) is
--based on a query found here: http://www.oracle.com/technology/oramag/code/tips2004/091304.html
select lvl, u.object_id, u.object_type, LPAD(' ', lvl) || object_name obj
FROM (SELECT level lvl, object_id
FROM SYS.public_dependency s
START WITH s.object_id = (select uo.object_id
from user_objects uo
where uo.object_name =
(select object_name from user_objects uo where uo.object_id = in_objID)
and uo.object_type = 'PACKAGE BODY')
CONNECT BY s.object_id = PRIOR referenced_object_id
GROUP BY level, object_id) tree, user_objects u
WHERE tree.object_id = u.object_id
and u.object_id <> in_objID --exclude self (requested Object ID) from list.
ORDER BY lvl desc;
begin
--loop through the dependencies
for r in c_getObjDepsByID(in_objID) loop
if fn_checkInList(trim(r.obj)) = false and (r.object_type = 'PACKAGE' or r.object_type = 'PACKAGE BODY') and
trim(r.obj) <> trim(in_name) then
dbms_output.put_line('checking deps of: ' || r.obj || ' ' || r.object_id || ' level: ' || r.lvl);
--now for each dependency, check the sub-dependency
sp_getDeps(r.object_id, trim(r.obj));
--add the object to the dependency list.
dep_list(i) := trim(r.obj);
i := i + 1;
end if;
end loop;
exception
when NO_DATA_FOUND then
dbms_output.put_line('no more data for: ' || in_objID);
end;

begin

for r in c_getObjDepsByNameAndType loop
dbms_output.put_line('top-level checking deps of: ' || r.obj || ' ' || r.object_id || ' level: ' || r.lvl);
sp_getDeps(r.object_id, trim(r.obj));
end loop;

dbms_output.put_line('dep count: ' || dep_list.count);
for j in 1 .. dep_list.count loop
dbms_output.put_line('obj: ' || j || ' ' || dep_list(j));
end loop;
end;

我知道这不是最漂亮的代码(遍布全局的代码等等),如果我今天下午有机会清理它,我可能会重新发布它,但是现在,它会生成一个构建订单似乎第一次运行没有问题。
:OBJECT_NAME应该是您要跟踪所有依赖关系和构建顺序的根对象。对我来说,这是一个具有单个方法的主程序包,它是系统其余部分的入口点。
:OBJECT_TYPE我主要限于 PACKAGE BODY,但是包括其他类型(例如触发器)应该不算太多。

最后一件事,由 :OBJECT_NAME指定的对象不会出现在输出中,但是它应该是最后一项,因此您必须手动将其添加到构建列表中。

更新:我刚刚发现了 user_dependenciesall_dependencies,现在可以使此代码更简单了。

最佳答案

如果您实际上只在处理PL/SQL软件包,则不需要大汗淋漓的构建顺序。只需先构建所有包装规范即可。然后,您可以部署所有程序包主体,它们将进行编译,因为它们的依赖关系是程序包规范。

如果您碰巧有一些依赖于其他规范的软件包规范-如果您有声明用于封装过程签名的常量,子类型或ref游标的软件包-那么您需要首先构建这些软件包规范。但是应该没有足够的数量,您可以手工将它们安排在构建脚本中。

编辑

It looks like they wil be doing incremental AND "clean-sweep" builds, so the build order will matter most for when they clean out the environment and rebuild it.



那并没有改变任何东西。

这是一个扩展的示例。我有一个包含三个程序包的模式。
SQL> select object_name, object_type, status
2 from user_objects
3 order by 1, 2
4 /

OBJECT_NAME OBJECT_TYPE STATUS
--------------- --------------- -------
PKG1 PACKAGE VALID
PKG1 PACKAGE BODY VALID
PKG2 PACKAGE VALID
PKG2 PACKAGE BODY VALID
PKG3 PACKAGE VALID
PKG3 PACKAGE BODY VALID

6 rows selected.

SQL>

有趣的是,PKG1中的过程从PKG2调用过程,PKG2中的过程从PKG3调用过程,而PKG3中的过程从PKG1调用过程。

问:该循环依赖项如何工作?
A. 这不是循环依赖项。
SQL> select name, type, referenced_name, referenced_type
2 from user_dependencies
3 where referenced_owner = user
4 /

NAME TYPE REFERENCED_NAME REFERENCED_TYPE
--------------- --------------- --------------- ---------------
PKG1 PACKAGE BODY PKG1 PACKAGE
PKG1 PACKAGE BODY PKG2 PACKAGE
PKG2 PACKAGE BODY PKG2 PACKAGE
PKG2 PACKAGE BODY PKG3 PACKAGE
PKG3 PACKAGE BODY PKG3 PACKAGE
PKG3 PACKAGE BODY PKG1 PACKAGE

6 rows selected.

SQL>

所有从属对象都是程序包主体,所有引用的对象都是程序包规范。因此,如果我不重建架构,那么使用什么顺序实际上都没有关系。首先我们垃圾...
SQL> drop package pkg1
2 /

Package dropped.

SQL> drop package pkg2
2 /

Package dropped.

SQL> drop package pkg3
2 /

Package dropped.

SQL>

然后我们重建...
SQL> create or replace package pkg3 is
2 procedure p5;
3 procedure p6;
4 end pkg3;
5 /

Package created.

SQL> create or replace package pkg2 is
2 procedure p3;
3 procedure p4;
4 end pkg2;
5 /

Package created.

SQL> create or replace package pkg1 is
2 procedure p1;
3 procedure p2;
4 end pkg1;
5 /

Package created.

SQL> create or replace package body pkg2 is
2 procedure p3 is
3 begin
4 pkg3.p5;
5 end p3;
6 procedure p4 is
7 begin
8 dbms_output.put_line('PKG2.P4');
9 end p4;
10 end pkg2;
11 /

Package body created.

SQL> create or replace package body pkg3 is
2 procedure p5 is
3 begin
4 dbms_output.put_line('PKG3.P5');
5 end p5;
6 procedure p6 is
7 begin
8 pkg1.p1;
9 end p6;
10 end pkg3;
11 /

Package body created.

SQL> create or replace package body pkg1 is
2 procedure p1 is
3 begin
4 dbms_output.put_line('PKG1.P1');
5 end p1;
6 procedure p2 is
7 begin
8 pkg2.p4;
9 end p2;
10 end pkg1;
11 /

Package body created.

SQL>

各个对象的顺序无关紧要。只需在软件包主体之前构建软件包规范即可。尽管那实际上并不重要...
SQL> create or replace package pkg4 is
2 procedure p7;
3 end pkg4;
4 /

Package created.

SQL> create or replace package body pkg4 is
2 procedure p7 is
3 begin
4 dbms_output.put_line('PKG4.P7::'||constants_pkg.whatever);
5 end p7;
6 end pkg4;
7 /

Warning: Package Body created with compilation errors.

SQL> show errors
Errors for PACKAGE BODY PKG4:

LINE/COL ERROR
-------- -----------------------------------------------------------------
4/9 PL/SQL: Statement ignored
4/43 PLS-00201: identifier 'CONSTANTS_PKG.WHATEVER' must be declared
SQL>
PKG4无效,因为我们尚未构建 CONSTANTS_PKG
SQL> create or replace package constants_pkg is
2 whatever constant varchar2(20) := 'WHATEVER';
3 end constants_pkg;
4 /

Package created.

SQL> select object_name, object_type, status
2 from user_objects
3 where status != 'VALID'
4 order by 1, 2
5 /

OBJECT_NAME OBJECT_TYPE STATUS
--------------- --------------- -------
PKG4 PACKAGE BODY INVALID

SQL>
SQL> set serveroutput on size unlimited
SQL> exec pkg4.p7
PKG4.P7::WHATEVER

PL/SQL procedure successfully completed.

SQL> select object_name, object_type, status
2 from user_objects
3 where status != 'VALID'
4 order by 1, 2
5 /

no rows selected

SQL>

总是使用 CREATE OR REPLACE构建的任何东西都会被创建,如果有错误,它只会被标记为INVALID。一旦我们直接或间接执行它,数据库就会为我们编译它。因此,顺序无关紧要。真的不是。

如果使用无效对象完成构建的想法与您有关-我对此表示同情,我们被告知不要使用破损的 window -您可以使用 utlrp脚本或在11g the UTL_RECOMP package中使用;两种方法都需要一个SYSDBA帐户。

编辑2

The process is based around a build tool which was built by the vendor of the product we are integrating with, which is why the only inputs I can give to the build process are a list of files in the order they need to be built in. If there is a compiler error, the build tool fails, we have to manually submit a request for a new build.



这是一个政治问题,而不是技术问题。这并不是说不能通过技术修复来解决政治问题,只是技术修复不是解决问题的最佳工具。祝你好运。

关于Oracle构建顺序和PL/SQL软件包依赖关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2187520/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com