Как отразить изменения DDL из одной схемы в другую?

У меня есть требование, чтобы структура архивной таблицы была такой же, как и основная таблица. Всякий раз, когда мы выполняем какой-либо DDL в основной таблице, я хочу, чтобы такой же DDL был и в архивной таблице. Пожалуйста, предложите, как я могу реализовать это в Oracle DB.

Рассмотрим ниже сценарий, в котором у меня есть 2 таблицы A.T1_TAB и B.T1_TAB_ARCH. Я добавляю столбец (ИМЯ VARCHAR2(30)) в A.T1_TAB. Мне нужно, чтобы тот же столбец был добавлен в B.T1_TAB_ARCH.

--SCHEMA B:
CREATE TABLE T1_TAB_ARCH(ID NUMBER);
--SCHEMA A:
CREATE TABLE T1_TAB(ID NUMBER);

ALTER TABLE T1_TAB ADD NAME VARCHAR2(30);--Added column in A.T1_TAB

Можем ли мы сделать это с помощью триггеров DDL или любым другим способом.

Также я хочу, чтобы эта функция была включена только для набора таблиц, которые я сохранил в отдельной таблице поиска.

Спасибо К


person Kapil    schedule 16.04.2018    source источник


Ответы (1)


Я могу дать вам свой триггер, который записывает каждый отдельный DDL в мою базу данных. Я использую этот триггер, когда мне нужно проверить производительность базы данных перед миграцией. Это помогает мне поддерживать вторую базу данных в актуальном состоянии. У меня много информации в этой таблице, последняя база данных, которую я использовал, имела размер 50 ТБ и более 200 пользователей.

CREATE TABLE SESSION_DDLS
(
  SID           NUMBER,
  SERIAL        NUMBER,
  USERNAME      VARCHAR2(30 BYTE),
  OSUSER        VARCHAR2(30 BYTE),
  MACHINE       VARCHAR2(64 BYTE),
  IP_ADDR       VARCHAR2(30 BYTE),
  PROCESS       VARCHAR2(15 BYTE),
  PROGRAM       VARCHAR2(48 BYTE),
  MODULE        VARCHAR2(48 BYTE),
  LOGON_TIME    DATE,
  DATE_CREATED  DATE,
  OWNER         VARCHAR2(30 BYTE),
  OBJECT_NAME   VARCHAR2(128 BYTE),
  OBJECT_TYPE   VARCHAR2(18 BYTE),
  EVENT         VARCHAR2(16 BYTE),
  SQL_TEXT      VARCHAR2(4000 BYTE)
)

CREATE OR REPLACE TRIGGER session_ddls
    BEFORE DDL
    ON DATABASE
DECLARE
    v_sid      NUMBER;
    sql_text   ora_name_list_t;
    stmt       VARCHAR2 ( 1000 ) := '';
    n          BINARY_INTEGER := 0;
BEGIN
    SELECT DISTINCT sid
      INTO v_sid
      FROM sys.v_$mystat;

    n := NVL ( ora_sql_txt ( sql_text ), 0 );

    FOR i IN 1 .. n
    LOOP
        stmt := SUBSTR ( stmt || sql_text ( i ), 1, 1000 );
    END LOOP;

    IF LOWER ( stmt ) LIKE '%identified by%' THEN
        stmt := SUBSTR ( stmt, 1, 20 );
    END IF;

    INSERT INTO o2o.session_ddls
        SELECT vses.sid,
               vses.serial#,
               vses.username,
               vses.osuser,
               vses.machine,
               SYS_CONTEXT ( 'userenv', 'ip_address' ),
               vses.process,
               vses.program,
               vses.module,
               vses.logon_time,
               SYSDATE,
               sys.dictionary_obj_owner,
               sys.dictionary_obj_name,
               sys.dictionary_obj_type,
               sys.sysevent,
               stmt
          FROM sys.v_$session vses
         WHERE vses.sid = v_sid;
END;
/

Я думаю, это хорошее начало для вас. Во-первых, вы должны фильтровать после DICTIONARY_OBJ_TYPE, потому что вас интересуют таблицы, во-вторых, вы можете реализовать некоторые фильтры для DICTIONARY_OBJ_OWNER и DICTIONARY_OBJ_NAME и, наконец, если хотите, вы можете выполнить оператор из SYSEVENT в своей таблице ARCH, но не не забудьте объединить свой суффикс ARCH в DICTIONARY_OBJ_NAME.

Если я не ясно выразился, пожалуйста, дайте мне знать.

Удачи!

person adimoise91    schedule 16.04.2018