Цикл зависимостей объектов Oracle

У меня проблема, когда я пытаюсь скомпилировать свой проект в Oracle Database. Чтобы сделать его более простым, у меня есть три объекта: 2 пакета (UTILS и TYPES) ​​и 1 вид (VIEW).

Пакет UTILS использует типы, определенные в TYPES пакета. Пакет TYPES использует VIEW в качестве основы для одного из его типов. И VIEW использует функции из пакета UTILS в нем script. Когда я пытаюсь внести некоторые изменения в один из этих объектов, я не могу скомпилировать, потому что все в недопустимом состоянии. Таким образом создается какой-то цикл зависимостей объектов.

Пожалуйста, помогите мне решить эту проблему.

Например, есть ли способ компилировать приведенный ниже код? Каждый объект индивидуально синтаксически корректен, но как все они могут быть скомпилированы вместе?

create or replace package my_types is
   type type1 is table of number;
   type type2 is table of my_view%rowtype;
end;
/

create or replace package my_utils is
   function get_1 return number;
   procedure do_something(parameter my_types.type2);
end;
/

create or replace package body my_utils is
   function get_1 return number is
   begin
       return 1;
   end;

   procedure do_something(parameter my_types.type2) is
   begin
       null;
   end;
end;
/

create or replace force view my_view as
select * from dual
where 1 = my_utils.get_1();

exec dbms_utility.compile_schema(user, false);

select object_name from user_objects where status <> 'VALID';

Ответ 1

Если вы не хотите/не можете разделить свой пакет или представление, вы всегда можете создать фиктивную версию своего представления, скомпилировать пакеты и создать "реальный" вид потом:

create or replace package my_types is
   type type1 is table of number;
   type type2 is table of my_view%rowtype;
end;
/

create or replace package my_utils is
   function get_1 return number;
   procedure do_something(parameter my_types.type2);
end;
/

create or replace package body my_utils is
   function get_1 return number is
   begin
       return 1;
   end;

   procedure do_something(parameter my_types.type2) is
   begin
       null;
   end;
end;
/

create or replace force view my_view as
select * from dual;

exec dbms_utility.compile_schema(user, false);

create or replace force view my_view as
select * from dual
where 1 = my_utils.get_1();

select object_name from user_objects where status <> 'VALID';

Ответ 2

Если вы нарушаете представление в двух представлениях, вы можете отключить циклическую зависимость:

create or replace view my_view_1
as select * from dual; 

create or replace package my_types is
   type type1 is table of number;
   type type2 is table of my_view_1%rowtype;
end;
/

create or replace package my_utils is
   function get_1 return number;
   procedure do_something(parameter my_types.type2);
end;
/

create or replace package body my_utils is
   function get_1 return number is
   begin
       return 1;
   end;

   procedure do_something(parameter my_types.type2) is
   begin
       null;
   end;
end;
/

create or replace view my_view as
select * from my_view_1
where 1 = my_utils.get_1();

EDIT: Еще одна возможность - разбить пакет my_utils на два:

create or replace package my_utils_1 is
   function get_1 return number;
end;
/
create or replace package body my_utils_1 is
   function get_1 return number is
   begin
       return 1;
   end;
end;
/

create or replace view my_view as
select * from dual
where 1 = my_utils_1.get_1();

create or replace package my_types is
   type type1 is table of number;
   type type2 is table of my_view%rowtype;
end;
/

create or replace package my_utils_2 is
   procedure do_something(parameter my_types.type2);
end;
/
create or replace package body my_utils_2 is
   procedure do_something(parameter my_types.type2) is
   begin
       null;
   end;
end;
/

Ответ 3

Я бы воздержался от использования упакованных типов и% ROWTYPE. Они не являются стандартными SQL и могут быть заменены на Структурированные типы

create or replace view my_view_1
as select * from dual; 

create or replace type type1 as table of number;
create or replace type type2 as object (DUMMY VARCHAR2(1 byte));
create or replace type table_type2 as table of type2;

create or replace package my_utils is
   function get_1 return number;
   procedure do_something(parameter table_type2);
end;
/

create or replace package body my_utils is
   function get_1 return number is
   begin
       return 1;
   end;

   procedure do_something(parameter table_type2) is
   begin
       null;
   end;
end;
/

create or replace view my_view as
select * from my_view_1
where 1 = my_utils.get_1();