DBMS_METADATA_DIFFといくつかのメタデータクエリにより、このプロセスを自動化できます。
この例は、6種類の変更を示しています。1)列の追加2)シーケンスのインクリメント3)テーブルの削除4)テーブルの作成5)ビューの変更6)エクステントの割り当て
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;
正解です。DBMS_METADATA_DIFFはCREATE
では機能しません。 またはDROP
。 1つのスキーマにのみ存在するオブジェクトを差分しようとすると、次のようなエラーメッセージが生成されます。
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
ただし、オブジェクトの削除と追加は、次のように簡単にスクリプト化できる場合があります。
--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"
変更は、次のようなSQLステートメントで処理できます。
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
これらの結果に関する注意事項:
- ADD_COLUMNは期待どおりに機能します。
- ALLOCATE_EXTENTはおそらく誤検知です。遅延セグメントの作成については、気にしないでください。システムに影響を与える可能性はほとんどありません。
- CHANGE_VIEWはまったく機能しません。ただし、以前のメタデータクエリと同様に、DBA_VIEWSを使用してこのスクリプトを作成する比較的簡単な方法があるはずです。
- INCREMENT_SEQUENCEはうまく機能しすぎます。ほとんどの場合、アプリケーションはシーケンス値を気にしません。しかし、物事が同期しなくなった場合、それらを変更する必要がある場合があります。この
RESTART START WITH
構文は非常に役立ちます。インデックスを削除または再作成したり、increment by
をいじったりする必要はありません。 複数回。この構文は12cマニュアルにはありません。実際、Googleのどこにも見つかりません。このパッケージは文書化されていない機能を使用しているようです。
その他の注意事項:
- パッケージが非常に遅くなる場合があります。
- サーバー上のネットワークリンクに問題がある場合は、両方のサーバーへのリンクを持つローカルインスタンスを介して実行する必要があります。
- 誤検知がある可能性があります。スペースだけの行が返されることもあります。
このプロセスを完全に自動化することが可能です。しかし、上記の問題と、すべてでの私の経験に基づいています このような自動化されたツールでは、100%信頼するべきではありません。