Estoy tratando de crear una lista de dependencias de paquetes PL/SQL para poder ayudar a configurar un script de compilación automatizado para que mis paquetes se ejecuten en el servidor de prueba. ¿Hay alguna manera de comenzar con un paquete único (un paquete "raíz" identificado por nombre, idealmente) y luego encontrar todas las dependencias y el orden en el que deben compilarse? Las dependencias ya están completamente resueltas en mi esquema personal (por lo que al menos tengo un lugar donde comenzar, pero ¿a dónde voy ahora?).Ordenes de compilación Oracle y dependencias de paquetes PL/SQL
(Oracle 10,2)
EDIT:
La herramienta de construcción que se utiliza utilizará el orden de construcción y será posible recuperar esos archivos con el fin de control de código fuente, y luego se pasa a Oracle a compilar (la herramienta de compilación propiamente dicha está escrita en Python o Java, o ambas cosas, no tengo acceso a la fuente). Básicamente, la herramienta de compilación necesita como entrada una lista de archivos para compilar en el orden en que deben compilarse en, y acceder a esos archivos en control de fuente. Si tiene eso, todo funcionará bastante bien.
EDIT:
Gracias por los guiones ordenadas. Desafortunadamente, el proceso de construcción está fuera de mis manos. El proceso se basa en una herramienta de compilación construida por el proveedor del producto con el que nos estamos integrando, y es por eso que las únicas entradas que puedo dar al proceso de compilación son una lista de archivos en el orden en que deben integrarse. Si hay un error de compilación, la herramienta de compilación falla, tenemos que enviar manualmente una solicitud para una compilación nueva. Entonces, una lista de archivos en el orden en que deberían compilarse es importante.
EDIT:
encontré esto: http://www.oracle.com/technology/oramag/code/tips2004/091304.html me da las dependencias de cualquier objeto. Ahora solo necesito obtener el pedido correcto ... Si obtengo algo que funcione lo publicaré aquí.
EDITAR: (con código)
Sé que, en general, este tipo de cosas no es necesario para Oracle, pero para cualquier persona que todavía está interesado ...
he improvisado un pequeño script que parece ser capaz de obtener una orden de construcción de tal manera que todos los paquetes serán construidas en el orden correcto sin errores basadas en la dependencia (con respecto a Pacakges) de la primera vez:
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;
que sé no es el código más bonito (globales por todos lados, etc ... ugh), y probablemente lo vuelva a publicar si puedo tener la oportunidad esta tarde de limpiarlo, pero en este momento, produce un orden de construcción que parece correr la primera vez sin problemas.
:OBJECT_NAME
debe ser el objeto raíz del que desea rastrear todas las dependencias y el orden de compilación. Para mí, este es un paquete principal con un único método que es el punto de entrada al resto del sistema.
:OBJECT_TYPE
Tengo restringido principalmente a PACKAGE BODY
, pero no debería ser demasiado trabajo para incluir otros tipos, como desencadenantes.
Una última cosa, el objeto especificado por :OBJECT_NAME
no aparecerá en la salida, pero debería ser el último elemento, por lo que deberá agregarlo manualmente a su lista de compilación.
ACTUALIZACIÓN: acabo de descubrir user_dependencies
y all_dependencies
, este código, probablemente se podría hacer mucho más simple ahora.
¿quiere decir paquetes de Oracle PL/SQL? –
La única manera que lo he hecho es guionarlo y probar la implementación en un esquema nuevo. Reordenar los paquetes en el script según sea necesario en función de los errores ... –
Sí, quise decir paquetes. – FrustratedWithFormsDesigner