Oracle-bauen, um-und PL/SQL-Paket-Abhängigkeiten

Ich versuche, den Aufbau einer Liste von PL/SQL-Paket-Abhängigkeiten, so dass ich kann helfen, richten Sie einen automatisierten build-Skript für meine Pakete laufen auf dem test-server. Gibt es einen Weg, um zu starten mit einem einzigen Paket (ein "root" - Paket mit seinem Namen identifiziert, im Idealfall) und dann finden all die Abhängigkeiten und die Reihenfolge müssen zusammengestellt werden?
Abhängigkeiten sind bereits vollständig gelöst in meinem persönlichen schema (also ich zumindest irgendwo zu beginnen - aber wohin gehe ich als Nächstes?).

(Oracle 10.2)

EDIT:

Das build-Werkzeug, das verwendet wird, verwenden Sie die build-Reihenfolge und wird retreive die Dateien in der Reihenfolge von der Quelle Kontrolle, und dann passieren Sie, um Oracle zu kompilieren (die aktuelle build-tool selbst ist in Python oder Java oder beides - ich habe keinen Zugriff auf die Quelle). Grundsätzlich ist das build-Werkzeug benötigt als Eingabe eine Liste von Dateien zu kompilieren in der Reihenfolge kompiliert werden müssen in, und der Zugang zu diesen Dateien in der Quellcodeverwaltung. Wenn es die hat, funktioniert alles Recht gut.

EDIT:

Danke für die nette scripts. Leider wird der build-Prozess wird meistens aus der Hand. Der Prozess basiert auf einem build-tool, das gebaut wurde, die durch den Hersteller des Produkts, werden wir die Integration mit der, die ist der Grund, warum die nur Eingänge, die ich geben kann, um den build-Prozess eine Liste von Dateien in der Reihenfolge, die Sie brauchen, um gebaut werden. Wenn es einen compiler-Fehler, den build-tool fehlschlägt, müssen wir manuell einen Antrag für einen neuen build. So eine Liste von Dateien in der Reihenfolge, wie Sie erstellt werden sollten, ist wichtig.

EDIT:

Gefunden: http://www.oracle.com/technology/oramag/code/tips2004/091304.html
Gibt mir die Abhängigkeiten eines Objekts. Jetzt brauche ich nur, um die Bestellung Recht... Wenn ich etwas arbeiten werde ich es hier posten.

EDIT: (mit code!)

Ich weiß, dass in der Regel diese Art der Sache ist nicht erforderlich für Oracle, aber für alle die es noch interessiert...

Habe ich zusammen gebastelt ein kleines Skript, das scheint zu sein, bauen Sie um, so dass alle Pakete, die gebaut werden in der richtigen Reihenfolge mit keine Abhängigkeit-bezogene Fehler (mit Bezug auf pacakges) das erste mal:

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 schönste code (globals alle über dem Platz, etc... igitt), und ich werde wohl umbuchen es, wenn ich die chance bekommen, an diesem Nachmittag, um es zu säubern, aber jetzt, erzeugt es eine build order, die scheint, zu laufen, die erste Zeit ohne Probleme.

:OBJECT_NAME sollte das root-Objekt, das Sie verfolgen möchten alle Abhängigkeiten und build-Reihenfolge. Für mich ist das Haupt-Paket mit einer einzigen Methode, die den Einstiegspunkt für den rest des Systems.

:OBJECT_TYPE Ich habe meist nur für PACKAGE BODY, aber es sollte nicht zu viel Arbeit, um auch andere Arten, wie Trigger.

Eine Letzte Sache, die angegebenen Objekts :OBJECT_NAME erscheinen nicht in der Ausgabe, aber es sollte das Letzte Element, so müssen Sie hinzufügen, dass zu Ihrer build-Liste manuell.

UPDATE: ich habe gerade entdeckt user_dependencies und all_dependencies dieser code konnte wahrscheinlich gemacht werden, viel einfacher jetzt.

  • meinst du Oracle PL/SQL-Pakete?
  • Nur die Art, wie ich es getan habe ist ein Skript, und testen, bereitstellen, um eine frische schema. Sortieren Sie die Pakete in der Skript, wie erforderlich, basierend auf den Fehlern...
  • Ja, ich meinte Pakete.
  • Ich vergaß zu erwähnen, dass die spc ' s geladen werden sollen, bevor bdy ist zu helfen, mit Paket.Funktion/gespeicherte Prozedur Auflösung. Sie sind getrennt, nicht das laden einer einzigen Datei (Dateiendung fällt mir ATM) - richtig?
  • Ponys: ja, wir wissen, haben wir eine Zusammenstellung aller Spezifikationen vor stellen. Das Hauptproblem ist die Reihenfolge der Spezifikationen. Ja, Sie sind in getrennten Dateien aus dem Körper.
Schreibe einen Kommentar