Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Oracle object dependency loop

I have a problem, when I try to compile my project in Oracle Database. To make it more simple, I have three objects: 2 packages (UTILS and TYPES) and 1 view (VIEW).

Package UTILS is using types defined in package TYPES. Package TYPES is using VIEW as a base for one of it's types. And VIEW is using functions from package UTILS in it's script. When I try to make some changes to one of these objects, I can't compile because everything is in invalid state. So some kind of object dependency loop is created.

Please help me to resolve this issue.

For example, is there anyway to compile the below code? Each object is individually syntactically correct, but how can they all be compiled together?

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';
like image 989
artbro Avatar asked Sep 05 '13 08:09

artbro


2 Answers

If you break view in two views, you can break cyclic dependency:

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: Another possibility is to break package my_utils in two:

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;
/
like image 114
igr Avatar answered Jan 04 '23 06:01

igr


I'd refrain from using packaged types and %ROWTYPE. These are not standard SQL and can be replaced by Structured Types

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();
like image 44
HAL 9000 Avatar answered Jan 04 '23 05:01

HAL 9000