sql >> Databáze >  >> RDS >> Oracle

automatizace rollback skriptu oracle

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 s increment 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 %.




  1. Jak mohu echo ID zdroje #6 z odpovědi MySql v PHP?

  2. ERD notace v datovém modelování

  3. Je nějaký rozdíl mezi IS NULL a =NULL

  4. 10 důvodů, proč zůstat u MySQL