Oracle对象依赖循环

时间:2013-09-05 08:08:39

标签: oracle oracle11g

当我尝试在Oracle数据库中编译项目时,我遇到了问题。为了使它更简单,我有三个对象:2个包(UTILS和TYPES)和1个视图(VIEW)。

包UTILS使用包TYPES中定义的类型。包TYPES使用VIEW作为其中一种类型的基础。 VIEW在其脚本中使用UTILS包中的函数。当我尝试对其中一个对象进行一些更改时,我无法编译,因为一切都处于无效状态。因此创建了某种对象依赖循环。

请帮我解决此问题。

例如,有没有编译下面的代码?每个对象在语法上都是正确的,但它们如何一起编译?

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';

3 个答案:

答案 0 :(得分:3)

如果在两个视图中断开视图,则可以打破循环依赖:

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();

编辑:另一种可能性是将包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;
/

答案 1 :(得分:2)

我不会使用打包类型和%ROWTYPE。这些不是标准SQL,可以替换为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();

答案 2 :(得分: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';