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
. Опитът за разлика на обект, който съществува само в една схема, ще генерира съобщение за грешка като това:
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%.