【问题标题】:How to mirror DDL changes from one schema to other?如何将 DDL 更改从一个模式镜像到另一个模式?
【发布时间】:2018-04-16 08:41:06
【问题描述】:

我需要保持存档表的结构与主表相同。每当我们在主表上执行一些 DDL 时,我也希望在存档表上也有相同的 DDL。请建议我如何在 Oracle DB 中实现它。

考虑下面的场景,我有 2 个表 A.T1_TAB 和 B.T1_TAB_ARCH。 我正在向 A.T1_TAB 添加一列 (NAME VARCHAR2(30))。我需要在 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 触发器或任何其他方式来实现吗?

我还希望仅对存储在单独查找表中的一组表启用此功能。

谢谢 克

【问题讨论】:

    标签: oracle triggers ddl


    【解决方案1】:

    我可以给你我的触发器,它会在我的数据库中写入每一个 DDL。当我必须在迁移之前测试数据库性能时,我正在使用此触发器。这有助于我使第二个数据库保持最新。我在这张表中有很多信息,我使用的最后一个数据库有 50TB 和超过 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 上实现一些过滤器,最后,如果需要,您可以在 ARCH 表上执行来自 SYSEVENT 的语句,但不要不要忘记在 DICTIONARY_OBJ_NAME 处连接您的 ARCH 后缀。

    如果我没有说清楚,请告诉我。

    祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-20
      • 2018-08-08
      • 2022-07-26
      • 1970-01-01
      • 2019-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多