sql >> Database teknologi >  >> RDS >> Oracle

automatisere rollback script oracle

DBMS_METADATA_DIFF og nogle få metadataforespørgsler kan automatisere denne proces.

Dette eksempel viser 6 typer ændringer:1) tilføjelse af en kolonne 2) forøgelse af en sekvens 3) droppe en tabel 4) oprettelse af en tabel 5) ændring af en visning 6) allokering af et omfang.

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;

Du har ret i, at DBMS_METADATA_DIFF ikke virker for CREATE eller DROP . Forsøger du at differentiere et objekt, der kun eksisterer i ét skema, genereres en fejlmeddelelse som denne:

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

Det kan dog være nemt at droppe og tilføje objekter med følgende:

--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" 

Ændringerne kan håndteres med en SQL-sætning som denne:

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

Nogle bemærkninger om disse resultater:

  • ADD_COLUMN fungerer som forventet.
  • ALLOCATE_EXTENT er sandsynligvis en falsk positiv, jeg tvivler på, at du bekymrer dig om udskudt segmentoprettelse. Det er meget usandsynligt, at det påvirker dit system.
  • CHANGE_VIEW virker slet ikke. Men som med de tidligere metadataforespørgsler burde der være en forholdsvis nem måde at bygge dette script på ved hjælp af DBA_VIEWS.
  • INCREMENT_SEQUENCE fungerer for godt. Det meste af tiden er en applikation ligeglad med sekvensværdierne. Men nogle gange, når tingene bliver ude af synkronisering, er du nødt til at ændre dem. Denne RESTART START WITH syntaks kan være meget nyttig. Du behøver ikke at droppe eller genskabe indekserne eller rode med increment by flere gange. Denne syntaks er ikke i 12c-manualen. Faktisk kan jeg ikke finde det nogen steder på Google. Det ser ud til, at denne pakke bruger udokumenterede funktioner.

Nogle andre bemærkninger:

  • Pakken kan nogle gange være meget langsom.
  • Hvis netværkslinks på serveren er et problem, skal du køre det gennem en lokal instans med links til begge servere.
  • Der kan være falske positiver. Nogle gange returnerer den en række med kun et mellemrum i.

Det er muligt at automatisere denne proces fuldt ud. Men baseret på ovenstående problemer og min erfaring med alle sådanne automatiserede værktøjer, bør du ikke stole 100% på det.




  1. Forholdet mellem katalog, skema, bruger og databaseinstans

  2. Gratis metoder til at reparere korrupt MySQL-database

  3. mysql tilsvarende datatyper

  4. Hvordan ændrer jeg datatypen for en kolonne i MySQL?