DBMS_METADATA_DIFF dan beberapa kueri metadata dapat mengotomatiskan proses ini.
Contoh ini menunjukkan 6 jenis perubahan:1) menambahkan kolom 2) menambah urutan 3) menjatuhkan tabel 4) membuat tabel 5) mengubah tampilan 6) mengalokasikan batas.
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;
Anda benar bahwa DBMS_METADATA_DIFF tidak berfungsi untuk CREATE
atau DROP
. Mencoba membedakan objek yang hanya ada dalam satu skema akan menghasilkan pesan kesalahan seperti ini:
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
Namun, menjatuhkan dan menambahkan objek mungkin mudah dilakukan dengan skrip berikut:
--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"
Perubahan dapat ditangani dengan pernyataan SQL seperti ini:
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
Beberapa catatan tentang hasil ini:
- ADD_COLUMN berfungsi seperti yang diharapkan.
- ALLOCATE_EXTENT mungkin positif palsu, saya ragu Anda peduli dengan pembuatan segmen yang ditangguhkan. Sangat kecil kemungkinannya untuk memengaruhi sistem Anda.
- CHANGE_VIEW tidak berfungsi sama sekali. Namun seperti kueri metadata sebelumnya, seharusnya ada cara yang relatif mudah untuk membuat skrip ini menggunakan DBA_VIEWS.
- INCREMENT_SEQUENCE bekerja terlalu baik. Sebagian besar waktu aplikasi tidak peduli dengan nilai urutan. Tetapi terkadang ketika ada sesuatu yang tidak sinkron, Anda perlu mengubahnya.
RESTART START WITH
. ini sintaks bisa sangat membantu. Anda tidak perlu menjatuhkan atau membuat ulang indeks, atau mengacaukanincrement by
beberapa kali. Sintaks ini tidak ada dalam manual 12c. Bahkan, saya tidak dapat menemukannya di mana pun di Google. Sepertinya paket ini menggunakan fitur tidak berdokumen.
Beberapa catatan lain:
- Paket terkadang bisa sangat lambat.
- Jika tautan jaringan di server menjadi masalah, Anda harus menjalankannya melalui instance lokal dengan tautan ke kedua server.
- Mungkin ada hasil positif palsu. Terkadang ia mengembalikan baris hanya dengan spasi di dalamnya.
Dimungkinkan untuk sepenuhnya mengotomatisasi proses ini. Tetapi berdasarkan masalah di atas, dan pengalaman saya dengan semua alat otomatis seperti itu, Anda tidak boleh mempercayainya 100%.