2013-09-05 38 views
10

Tôi gặp sự cố, khi tôi cố gắng biên dịch dự án của mình trong Cơ sở dữ liệu Oracle. Để làm cho nó đơn giản hơn, tôi có ba đối tượng: 2 gói (UTILS và TYPES) ​​và 1 view (VIEW).Vòng lặp phụ thuộc đối tượng Oracle

Gói UTILS đang sử dụng các loại được xác định trong TYPES gói. TYPES gói đang sử dụng VIEW làm cơ sở cho một trong các loại đó. Và VIEW đang sử dụng các hàm từ gói UTILS trong tập lệnh của nó. Khi tôi cố gắng thực hiện một số thay đổi đối với một trong các đối tượng này, tôi không thể biên dịch được vì mọi thứ đều ở trạng thái không hợp lệ. Vì vậy, một số loại phụ thuộc đối tượng vòng lặp được tạo ra.

Vui lòng giúp tôi giải quyết vấn đề này.

Ví dụ: có cách nào để biên dịch mã bên dưới không? Mỗi đối tượng là một cú pháp chính xác, nhưng làm thế nào tất cả chúng có thể được biên dịch cùng nhau?

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

Phá vỡ chu kỳ? Thực hiện các chức năng một hiệu ứng thời gian chạy (thay vì được đưa vào truy vấn) - ví dụ: THỰC HÀNH chức năng từ một chuỗi. –

+0

SO phá vỡ vòng lặp là cách duy nhất ra khỏi vấn đề này? Tôi nghĩ rằng có thể có một số gợi ý khi biên dịch gói/xem để bỏ qua trạng thái không hợp lệ của các phụ thuộc của nó. – artbro

+0

Không có ý tưởng - bạn sẽ muốn một số oracle biết-it-all :-) Tôi quen thuộc hơn với Postgres và đó là cách tôi sẽ làm điều đó ở đó. (nó không bị vấn đề * chính xác * đó, nhưng bạn vẫn có thể tạo các vòng phụ thuộc). –

Trả lời

1

Nếu bạn không muốn/không thể phân chia gói hoặc chế độ xem của mình, bạn luôn có thể tạo phiên bản giả của chế độ xem trước, biên dịch các gói và tạo chế độ xem "thực" sau:

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

Điều này không hoạt động trên 11.2.0.3.0. Thủ thuật giả phiên bản hoạt động cho các phụ thuộc 2 chiều đơn giản, nhưng dường như không hoạt động trong tình huống này. –

+1

@jonearles Tôi đã thử nghiệm nó trên 11.1.0.6, nơi nó hoạt động tốt. Nếu bạn thử nghiệm nó trên 11.2.0.3 - tất cả các đối tượng không hợp lệ sau khi biên dịch lại? –

+1

Có, tất cả đều không hợp lệ. Nó cũng không thành công trên Express Edition, 11.2.0.2, đây là [SQL Fiddle] (http://sqlfiddle.com/#!4/44f94/1). Có lẽ đó là một lỗi trong 11.2, nhưng tôi không thể tìm thấy bất cứ điều gì về Hỗ trợ Oracle. –

3

Nếu bạn phá vỡ quan điểm trong hai quan điểm, bạn có thể phá vỡ sự phụ thuộc theo chu kỳ:

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: Một khả năng khác là để phá vỡ my_utils gói trong hai:

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; 
/
+0

+1 Đây là một giải pháp có thể, nhưng đối với tiền thưởng tôi đang tìm kiếm một cái gì đó tốt hơn một chút. Tạo hai chế độ xem không lý tưởng vì chúng cần phải được đồng bộ hóa. Và trong một kịch bản thực tế hơn, chế độ xem không thể tách rời dễ dàng mà không sao chép rất nhiều logic. –

2

Tôi không sử dụng các loại đóng gói và% ROWTYPE. Đây không phải là SQL tiêu chuẩn và có thể được thay thế bằng 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(); 
+0

Không chắc SQL chuẩn đưa vào bảng ở đây. Tùy thuộc vào cách sử dụng kiểu đối tượng (mà chúng ta không thấy ở đây), nó có thể phạt hiệu suất ... – igr

+0

Loại đóng gói và% ROWTYPE chỉ có thể được sử dụng trong PL/SQL. Bạn không thể SELECT chúng bằng cách sử dụng các truy vấn SQL hoặc các khung nhìn. Hiệu suất-khôn ngoan họ sẽ không có nhiều khác nhau –

Các vấn đề liên quan