DBMS_METADATA_DIFF a několik dotazů na metadata mohou tento proces automatizovat.
Tento příklad ukazuje 6 typů změn:1) přidání sloupce 2) zvýšení sekvence 3) zrušení tabulky 4) vytvoření tabulky 5) změna pohledu 6) přidělení rozsahu.
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;
Máte pravdu, že DBMS_METADATA_DIFF nefunguje pro CREATE
nebo DROP
. Pokus o porovnání objektu, který existuje pouze v jednom schématu, vygeneruje chybovou zprávu, jako je tato:
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
Vypouštění a přidávání objektů však může být snadné skriptovat pomocí následujícího:
--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"
Změny lze zpracovat pomocí příkazu SQL takto:
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
Několik poznámek k těmto výsledkům:
- ADD_COLUMN funguje podle očekávání.
- ALLOCATE_EXTENT je pravděpodobně falešně pozitivní, pochybuji, že vám záleží na odloženém vytvoření segmentu. Je velmi nepravděpodobné, že by to ovlivnilo váš systém.
- CHANGE_VIEW vůbec nefunguje. Ale stejně jako u předchozích dotazů na metadata by měl existovat relativně snadný způsob, jak vytvořit tento skript pomocí DBA_VIEWS.
- INCREMENT_SEQUENCE funguje příliš dobře. Aplikace se většinou nestará o sekvenční hodnoty. Ale někdy, když se věci nesynchronizují, je potřeba je změnit. Toto
RESTART START WITH
syntaxe může být velmi užitečná. Nemusíte rušit nebo znovu vytvářet indexy nebo si zahrávat sincrement by
vícekrát. Tato syntaxe není v příručce 12c. Ve skutečnosti to nemůžu najít nikde na Googlu. Zdá se, že tento balíček používá nezdokumentované funkce.
Některé další poznámky:
- Balík může být někdy velmi pomalý.
- Pokud jsou problémem síťové odkazy na serveru, budete jej muset spustit prostřednictvím místní instance s odkazy na oba servery.
- Mohou existovat falešně pozitivní výsledky. Někdy vrátí řádek s pouze mezerou.
Tento proces je možné plně automatizovat. Ale na základě výše uvedených problémů a mých zkušeností se všemi takovým automatizovaným nástrojům byste neměli věřit na 100 %.