Oracle
 sql >> Baza danych >  >> RDS >> Oracle

automatyzacja wyrocznia skryptu wycofywania

DBMS_METADATA_DIFF i kilka zapytań o metadane może zautomatyzować ten proces.

Ten przykład ilustruje 6 typów zmian:1) dodanie kolumny 2) zwiększenie sekwencji 3) usunięcie tabeli 4) utworzenie tabeli 5) zmiana widoku 6) przypisanie zakresu.

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;

Masz rację, że DBMS_METADATA_DIFF nie działa dla CREATE lub DROP . Próba porównania obiektu, który istnieje tylko w jednym schemacie, wygeneruje komunikat o błędzie podobny do tego:

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

Jednak upuszczanie i dodawanie obiektów może być łatwe do napisania w następujący sposób:

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

Zmiany można obsługiwać za pomocą instrukcji SQL w następujący sposób:

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

Kilka uwag na temat tych wyników:

  • ADD_COLUMN działa zgodnie z oczekiwaniami.
  • ALLOCATE_EXTENT jest prawdopodobnie fałszywym alarmem, wątpię, czy zależy Ci na tworzeniu odroczonego segmentu. Jest bardzo mało prawdopodobne, że wpłynie to na twój system.
  • CHANGE_VIEW w ogóle nie działa. Ale podobnie jak w przypadku poprzednich zapytań o metadane, powinien istnieć stosunkowo łatwy sposób na zbudowanie tego skryptu przy użyciu DBA_VIEWS.
  • INCREMENT_SEQUENCE działa zbyt dobrze. W większości przypadków aplikacja nie dba o wartości sekwencji. Ale czasami, gdy coś nie jest zsynchronizowane, musisz je zmienić. To RESTART START WITH składnia może być bardzo pomocna. Nie musisz usuwać ani ponownie tworzyć indeksów, ani bałaganić z increment by wiele razy. Ta składnia nie znajduje się w podręczniku 12c. W rzeczywistości nie mogę go znaleźć nigdzie w Google. Wygląda na to, że ten pakiet używa nieudokumentowanych funkcji.

Kilka innych notatek:

  • Pakiet może czasami być bardzo powolny.
  • Jeśli łącza sieciowe na serwerze stanowią problem, musisz uruchomić go przez lokalną instancję z łączami do obu serwerów.
  • Mogą występować fałszywe alarmy. Czasami zwraca wiersz zawierający tylko spację.

Istnieje możliwość pełnej automatyzacji tego procesu. Ale w oparciu o powyższe problemy i moje doświadczenie ze wszystkimi takich zautomatyzowanych narzędzi, nie powinieneś ufać im w 100%.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. BatchUpdateException:partia nie zostanie zakończona

  2. Jaka jest różnica między pls_integer a binary_integer?

  3. Wyrocznia SQL wielokrotnego wstawiania

  4. Nie można przesłać połączenia do pliku oracle.jdbc.OracleConnection

  5. ORA-00054:zasób zajęty i pozyskiwanie za pomocą NOWIT określone