DBMS_METADATA_DIFF và một số truy vấn siêu dữ liệu có thể tự động hóa quá trình này.
Ví dụ này minh họa 6 loại thay đổi:1) thêm cột 2) tăng chuỗi 3) giảm bảng 4) tạo bảng 5) thay đổi chế độ xem 6) phân bổ phạm vi.
create table user1.add_column(id number);
create table user2.add_column(id number);
alter table user2.add_column add some_column number(5);
create sequence user1.increment_sequence nocache;
select user1.increment_sequence.nextval from dual;
select user1.increment_sequence.nextval from dual;
create sequence user2.increment_sequence nocache;
select user2.increment_sequence.nextval from dual;
create table user1.drop_table(id number);
create table user2.create_table(id number);
create view user1.change_view as select 1 a from dual;
create view user2.change_view as select 2 a from dual;
create table user1.allocate_extent(id number);
create table user2.allocate_extent(id number);
insert into user2.allocate_extent values(1);
rollback;
Bạn đúng rằng DBMS_METADATA_DIFF không hoạt động cho CREATE
hoặc DROP
. Cố gắng khác biệt một đối tượng chỉ tồn tại trong một lược đồ sẽ tạo ra một lỗi giống như sau:
ORA-31603: object "EXTRA_TABLE" of type TABLE not found in schema "USER1"
ORA-06512: at "SYS.DBMS_METADATA", line 7944
ORA-06512: at "SYS.DBMS_METADATA_DIFF", line 712
Tuy nhiên, việc thả và thêm các đối tượng có thể dễ dàng tạo kịch bản như sau:
--Dropped objects
select 'DROP '||object_type||' USER1.'||object_name v_sql
from
(
select object_name, object_type from dba_objects where owner = 'USER1'
minus
select object_name, object_type from dba_objects where owner = 'USER2'
);
V_SQL
-----
DROP TABLE USER1.DROPPED_TABLE
--Added objects
select dbms_metadata.get_ddl(object_type, object_name, 'USER2') v_sql
from
(
select object_name, object_type from dba_objects where owner = 'USER2'
minus
select object_name, object_type from dba_objects where owner = 'USER1'
);
V_SQL
-----
CREATE TABLE "USER2"."CREATED_TABLE"
( "ID" NUMBER
) SEGMENT CREATION DEFERRED
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
TABLESPACE "USERS"
Các thay đổi có thể được xử lý bằng một câu lệnh SQL như sau:
select object_name, object_type, dbms_metadata_diff.compare_alter(
object_type => object_type,
name1 => object_name,
name2 => object_name,
schema1 => 'USER2',
schema2 => 'USER1',
network_link1 => 'MYSELF',
network_link2 => 'MYSELF') difference
from
(
select object_name, object_type from dba_objects where owner = 'USER1'
intersect
select object_name, object_type from dba_objects where owner = 'USER2'
) objects;
OBJECT_NAME OBJECT_TYPE DIFFERENCE
----------- ----------- ----------
ADD_COLUMN TABLE ALTER TABLE "USER2"."ADD_COLUMN" DROP ("SOME_COLUMN")
ALLOCATE_EXTENT TABLE -- ORA-39278: Cannot alter table with segments to segment creation deferred.
CHANGE_VIEW VIEW -- ORA-39308: Cannot alter attribute of view: SUBQUERY
INCREMENT_SEQUENCE SEQUENCE ALTER SEQUENCE "USER2"."INCREMENT_SEQUENCE" RESTART START WITH 3
Một số lưu ý về các kết quả này:
- ADD_COLUMN hoạt động như mong đợi.
- ALLOCATE_EXTENT có thể là một dương tính giả, tôi nghi ngờ bạn quan tâm đến việc tạo phân đoạn bị hoãn lại. Nó rất ít có khả năng ảnh hưởng đến hệ thống của bạn.
- CHANGE_VIEW hoàn toàn không hoạt động. Nhưng cũng giống như các truy vấn siêu dữ liệu trước đó, sẽ có một cách tương đối dễ dàng để tạo tập lệnh này bằng cách sử dụng DBA_VIEWS.
- INCREMENT_SEQUENCE hoạt động quá tốt. Hầu hết thời gian một ứng dụng không quan tâm đến các giá trị trình tự. Nhưng đôi khi mọi thứ không đồng bộ, bạn cần phải thay đổi chúng.
RESTART START WITH
này cú pháp có thể rất hữu ích. Bạn không cần phải giảm hoặc tạo lại các chỉ mục hoặc gây rối với số gia tăngincrement by
nhiều lần. Cú pháp này không có trong sách hướng dẫn 12c. Trên thực tế, tôi không thể tìm thấy nó ở bất cứ đâu trên Google. Có vẻ như gói này đang sử dụng các tính năng không có giấy tờ.
Một số lưu ý khác:
- Đôi khi gói có thể rất chậm.
- Nếu các liên kết mạng trên máy chủ là sự cố, bạn sẽ cần chạy nó thông qua một phiên bản cục bộ với các liên kết đến cả hai máy chủ.
- Có thể có kết quả dương tính giả. Đôi khi, nó trả về một hàng chỉ với một khoảng trắng trong đó.
Có thể tự động hóa hoàn toàn quá trình này. Nhưng dựa trên các vấn đề ở trên và kinh nghiệm của tôi với tất cả những công cụ tự động như vậy, bạn không nên tin tưởng nó 100%.