DBMS_METADATA_DIFF und einige Metadatenabfragen können diesen Prozess automatisieren.
Dieses Beispiel zeigt 6 Arten von Änderungen:1) Hinzufügen einer Spalte 2) Inkrementieren einer Sequenz 3) Löschen einer Tabelle 4) Erstellen einer Tabelle 5) Ändern einer Ansicht 6) Zuweisen eines Extents.
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;
Sie haben Recht, dass DBMS_METADATA_DIFF nicht für CREATE
funktioniert oder DROP
. Der Versuch, ein Objekt zu unterscheiden, das nur in einem Schema existiert, erzeugt eine Fehlermeldung wie diese:
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
Das Löschen und Hinzufügen von Objekten kann jedoch mit dem folgenden Skript einfach sein:
--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"
Die Veränderungen können mit einer SQL-Anweisung wie dieser behandelt werden:
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
Einige Anmerkungen zu diesen Ergebnissen:
- ADD_COLUMN funktioniert wie erwartet.
- ALLOCATE_EXTENT ist wahrscheinlich falsch positiv, ich bezweifle, dass Sie sich für die verzögerte Segmenterstellung interessieren. Es ist sehr unwahrscheinlich, dass Ihr System beeinträchtigt wird.
- CHANGE_VIEW funktioniert überhaupt nicht. Aber wie bei den vorherigen Metadatenabfragen sollte es eine relativ einfache Möglichkeit geben, dieses Skript mit DBA_VIEWS zu erstellen.
- INCREMENT_SEQUENCE funktioniert zu gut. Meistens kümmert sich eine Anwendung nicht um die Sequenzwerte. Aber manchmal, wenn die Dinge nicht mehr synchron sind, müssen Sie sie ändern. Dieser
RESTART START WITH
Syntax kann sehr hilfreich sein. Sie müssen die Indizes nicht löschen oder neu erstellen oder mitincrement by
herumspielen mehrmals. Diese Syntax steht nicht im 12c-Handbuch. Tatsächlich finde ich es nirgendwo bei Google. Sieht so aus, als würde dieses Paket undokumentierte Funktionen verwenden.
Einige andere Anmerkungen:
- Das Paket kann manchmal sehr langsam sein.
- Wenn Netzwerkverbindungen auf dem Server ein Problem darstellen, müssen Sie es über eine lokale Instanz mit Verbindungen zu beiden Servern ausführen.
- Es kann zu Fehlalarmen kommen. Manchmal gibt es eine Zeile mit nur einem Leerzeichen zurück.
Es ist möglich, diesen Prozess vollständig zu automatisieren. Aber basierend auf den oben genannten Problemen und meiner Erfahrung mit allen solchen automatisierten Tools sollten Sie diesen nicht zu 100 % vertrauen.