2010-06-29 6 views
8

Tôi đang gặp khó khăn để trích xuất DDL cho một lược đồ đã cho bằng DBMS_METADATA, có lẽ vì sự hiểu biết của tôi về nó là sai.Làm thế nào để có được một SCHEMA Oracle như các kịch bản DDL với DBMS_METADATA (và SCHEMA_EXPORT)

Dưới đây là những gì tôi về cơ bản làm:

set termout off 

create table copy_dml_schema(c clob, i number); 

declare 

    m number; 
    t number; 
    e number; 
    c clob; 
    i number := 0; 

begin 

    e := dbms_metadata.session_transform; 


    dbms_metadata.set_transform_param (e, 'REF_CONSTRAINTS'  , false ); 
    dbms_metadata.set_transform_param (e, 'CONSTRAINTS_AS_ALTER', true ); 
    dbms_metadata.set_transform_param (e, 'CONSTRAINTS'   , true ); 
    dbms_metadata.set_transform_param (e, 'FORCE'    , true ); 


    m := dbms_metadata.open('SCHEMA_EXPORT'); 
    t := dbms_metadata.add_transform (m, 'DDL'     ); 

    dbms_metadata.set_transform_param (t, 'PRETTY'    , true ); 
    dbms_metadata.set_transform_param (t, 'SQLTERMINATOR'  , true ); 

    dbms_metadata.set_filter   (m, 'SCHEMA'    , 'XYZ'); 
    dbms_metadata.set_filter   (m, 'EXCLUDE_PATH_EXPR' , 'in (' || 
              '''GRANT''   ,' || 
              '''SYNONYM''  ,' || 
              '''STATISTICS''  ,' || 
              '''COMMENT''   ' || 
              ')'); 


    loop 
    c := dbms_metadata.fetch_clob(m); 
    exit when c is null; 
    insert into copy_dml_schema values (c, i); 
    i := i+1; 
    end loop; 

    dbms_metadata.close(m); 

end; 
/

commit; 


set pages  0 
set trimspool on 
set long  1000000 
set lines   300 
set longchunksize 300 


spool c:\temp\the_schema.sql 

select 
    c 
from 
    copy_dml_schema 
order 
    by i; 

spool off 

drop table copy_dml_schema; 

set termout on 

Tôi đã theo ấn tượng rằng phương pháp này sẽ quay trở lại những điều khoản về "CREATE TABLE" để sao cho chúng có thể được tạo ra, có nghĩa là, bảng phụ thuộc sẽ được phát ra một lát sau.

Tuy nhiên, hóa ra thứ tự của các bảng là tùy ý ở chỗ một số bảng được phát ra với ràng buộc khóa ngoài tham chiếu đến bảng chưa được phát ra.

Để "giải quyết" vấn đề này, tôi đặt số REF_CONSTRAINTCONSTRAINTS_AS_ALTER thành sai và đúng, vì tôi cho rằng điều này sẽ làm cho sự cố của tôi biến mất. Đó không phải là trường hợp.

Vì vậy, có một vấn đề xung quanh vấn đề của tôi hay có một cài đặt mà tôi bỏ qua không?

+0

Câu hỏi hay. Rất mong nhận được câu trả lời. – Rene

Trả lời

1

Không quá nhiều câu trả lời là quan sát. Về mặt kỹ thuật thì có thể (nhưng có lẽ là trong thực tế) để có tham chiếu vòng tròn trong các ràng buộc.

create table blue (blue_id number primary key, val varchar2(10), red_id number); 
create table red (red_id number primary key, val varchar2(10), blue_id number); 

insert into blue values (1,'test',2); 
insert into red values (2,'test',1); 

alter table blue add constraint blue_fk foreign key (red_id) references red (red_id); 
alter table red add constraint red_fk foreign key (blue_id) references blue (blue_id); 

Vì vậy, tôi có thể hiểu nếu họ quyết định điều đó, bởi vì nó không nhất thiết phải luôn đạt được, họ sẽ không bận tâm đặt các đối tượng theo thứ tự phụ thuộc.

Như vậy, tôi sẽ để lại các ràng buộc tham chiếu khi các bảng đang được tạo, sau đó áp dụng chúng như ALTERs sau khi tất cả các bảng đã được tạo.

+0

Có, tôi biết về các tham chiếu vòng tròn và họ sẽ cấm tạo bảng trong một lần. Nhưng theo như tôi hiểu tài liệu, đây chính xác là lý do để đặt 'REF_CONSTRAINT' thành false và' CONSTRAINTS_AS_ALTER' thành true để các ràng buộc tham chiếu không được tạo thành một phần của câu lệnh 'create table' nhưng sau đó là' alter table 'riêng biệt ... ràng buộc ... tuyên bố khóa ngoài '. –