sql >> Database >  >> RDS >> Oracle

het automatiseren van rollback script oracle

DBMS_METADATA_DIFF en een paar metadataquery's kunnen dit proces automatiseren.

Dit voorbeeld demonstreert 6 soorten wijzigingen:1) een kolom toevoegen 2) een reeks verhogen 3) een tabel laten vallen 4) een tabel maken 5) een weergave wijzigen 6) een bereik toewijzen.

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;

Je hebt gelijk dat DBMS_METADATA_DIFF niet werkt voor CREATE of DROP . Als u probeert een object te differentiëren dat slechts in één schema bestaat, wordt een foutmelding als deze gegenereerd:

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

Het neerzetten en toevoegen van objecten kan echter gemakkelijk te scripten zijn met het volgende:

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

De wijzigingen kunnen worden afgehandeld met een SQL-statement als volgt:

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

Enkele opmerkingen over deze resultaten:

  • ADD_COLUMN werkt zoals verwacht.
  • ALLOCATE_EXTENT is waarschijnlijk een vals positief, ik betwijfel of u geïnteresseerd bent in het maken van uitgestelde segmenten. Het is zeer onwaarschijnlijk dat het uw systeem beïnvloedt.
  • CHANGE_VIEW werkt helemaal niet. Maar net als bij de vorige metadata-query's, zou er een relatief eenvoudige manier moeten zijn om dit script te bouwen met DBA_VIEWS.
  • INCREMENT_SEQUENCE werkt te goed. Meestal geeft een toepassing niets om de volgordewaarden. Maar soms, als dingen niet meer synchroon lopen, moet je ze veranderen. Deze RESTART START WITH syntaxis kan erg handig zijn. U hoeft de indexen niet te verwijderen of opnieuw te maken, of te knoeien met de increment by meerdere keren. Deze syntax staat niet in de 12c handleiding. Sterker nog, ik kan het nergens op Google vinden. Het lijkt erop dat dit pakket ongedocumenteerde functies gebruikt.

Enkele andere opmerkingen:

  • Het pakket kan soms erg traag zijn.
  • Als netwerkkoppelingen op de server een probleem vormen, moet u deze via een lokale instantie met koppelingen naar beide servers uitvoeren.
  • Er kunnen valse positieven zijn. Soms retourneert het een rij met alleen een spatie erin.

Het is mogelijk om dit proces volledig te automatiseren. Maar op basis van de bovenstaande problemen en mijn ervaring met allen dergelijke geautomatiseerde tools, je moet het niet 100% vertrouwen.




  1. ORACLE SQL:Vul ontbrekende datums in

  2. De schoonste manier om een ​​SQL-string in Java te bouwen

  3. Bereken percentiel van frequentie in MySQL

  4. fout bij het invoegen van android.database.sqlite.sqliteconstraintexception foutcode 19 beperking mislukt