Ich versuche, eine Liste der PL/SQL-Paketabhängigkeiten aufzubauen, damit ich ein automatisiertes Build-Skript für meine Pakete auf dem Testserver ausführen kann. Gibt es eine Möglichkeit, mit einem einzelnen Paket (einem "root" -Paket, das idealerweise namentlich identifiziert wird) zu beginnen und dann alle Abhängigkeiten und die Reihenfolge zu finden, in der sie kompiliert werden müssen? Abhängigkeiten sind bereits vollständig in meinem persönlichen Schema gelöst (so muss ich zumindest irgendwo anfangen - aber wohin gehe ich als nächstes?).Oracle Build-Reihenfolge und PL/SQL-Paket Abhängigkeiten
(Oracle 10,2)
EDIT:
Das Build-Tool, das verwendet wird, um die Erstellungsreihenfolge verwenden und diese Dateien in der Reihenfolge von Quellensteuerung, retreive und dann an Oracle gibt sie an kompilieren (das eigentliche Build-Tool selbst ist in Python oder Java oder beides geschrieben - ich habe keinen Zugriff auf die Quelle). Im Grunde benötigt das Build-Tool eine Liste von Dateien, die kompiliert werden müssen, um in der Reihenfolge zu kompilieren, in der sie in kompiliert werden müssen, und Zugriff auf diese Dateien in der Quellcodeverwaltung. Wenn es das hat, wird alles ganz gut funktionieren.
EDIT:
Danke für die ordentlich Skripte. Leider liegt der Build-Prozess größtenteils außerhalb meiner Hände. Der Prozess basiert auf einem Build-Tool, das vom Hersteller des Produkts, mit dem wir arbeiten, erstellt wurde. Aus diesem Grund kann ich dem Build-Prozess nur eine Liste von Dateien in der Reihenfolge geben, in der sie erstellt werden müssen. Wenn ein Compilerfehler auftritt, schlägt das Build-Tool fehl, wir müssen manuell eine Anfrage für einen neuen Build einreichen. Daher ist eine Liste von Dateien in der Reihenfolge wichtig, in der sie kompiliert werden sollten.
EDIT:
Gefunden dies: http://www.oracle.com/technology/oramag/code/tips2004/091304.html Gibt mir die Abhängigkeiten eines Objekts. Jetzt muss ich nur noch Ordnung schaffen ... Wenn etwas funktioniert, werde ich es hier posten.
EDIT: (! Mit Code)
Ich weiß, dass in der Regel diese Art der Sache für Oracle nicht erforderlich ist, sondern für jeden, der nach wie vor interessiert ...
Ich habe zusammengeschustert ein kleines Skript, das das erste Mal in der richtigen Reihenfolge ohne Abhängigkeitsfehler gebaut werden eine Build-Reihenfolge, so dass alle Pakete bekommen zu können, scheint sein (zu Pacakges in Bezug):
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;
ich weiß, es ist nicht der hübscheste Code (Globals überall, etc ... ugh), und ich werde es wahrscheinlich erneut veröffentlichen, wenn ich heute Nachmittag die Chance bekomme, es aufzuräumen, aber im Moment produziert es eine Build-Reihenfolge, die scheint das erste Mal ohne Probleme zu laufen.
:OBJECT_NAME
sollte das Stammobjekt sein, das Sie alle Abhängigkeiten verfolgen und Reihenfolge von erstellen möchten. Für mich ist dies ein Hauptpaket mit einer einzigen Methode, die den Einstiegspunkt für den Rest des Systems darstellt.
:OBJECT_TYPE
Ich habe meist auf PACKAGE BODY
beschränkt, aber es sollte nicht zu viel Arbeit sein, um andere Arten, wie zum Beispiel Trigger.
Eine letzte Sache, das Objekt von :OBJECT_NAME
angegeben wird nicht in der Ausgabe angezeigt, aber es sollte das letzte Element sein, also müssen Sie das zu Ihrer Build-Liste manuell hinzufügen.
UPDATE: Ich habe gerade entdeckt user_dependencies
und all_dependencies
könnte dieser Code wahrscheinlich jetzt viel einfacher gemacht werden.
meinen Sie Oracle PL/SQL-Pakete? –
Ich habe es nur gemacht, um es zu skripten und die Bereitstellung in einem neuen Schema zu testen. Ordnen Sie die Pakete im Skript nach Bedarf neu an, basierend auf Fehlern ... –
Ja, ich meinte Pakete. – FrustratedWithFormsDesigner