【问题标题】:How should I migrate DDL changes from one environment to the next?我应该如何将 DDL 更改从一种环境迁移到另一种环境?
【发布时间】:2010-03-08 20:35:07
【问题描述】:

我使用 SQL Developer 的 GUI 进行 DDL 更改。问题是,我需要将这些相同的更改应用于测试环境。我想知道其他人如何处理这个问题。目前我不得不手动编写 ALTER 语句以使测试环境与开发环境保持一致,但这很容易出错(两次做同样的事情)。在测试环境中没有重要数据的情况下,我通常只是把所有东西都吹走,从 dev 中导出 DDL 脚本并在测试中从头开始运行它们。

我知道有可以存储每个 DDL 更改的触发器,但这是一个高度共享的环境,我希望尽可能避免这种情况。

也许我应该只手动编写 DDL 内容而不是使用 GUI?

【问题讨论】:

  • 这就是我们在上一家商店使用的方法——通过脚本。分解成组件:表、索引、约束...有时在删除/禁用和重新创建之间细分。
  • @OMG Ponies 您的意思是手动编写每个脚本并对其进行版本控制,或者您有一个自动脚本/触发器来跟踪它们并对其进行分类?
  • @RI:手动。我们的客户使用了 Oracle Designer,有人告诉我它不可靠。

标签: sql database oracle ddl


【解决方案1】:

我已经看到了一种我不知道有多少种方法试图处理这个问题,最后我认为你只需要维护手动脚本。

现在,您不一定要自己写。在 MSSQL 中,当您进行更改时,有一个生成脚本的小按钮,它将为您所做的更改生成一个 SQL 脚本。我知道您说的是 Oracle,我使用他们的 GUI 已经有几年了,但我只能想象它们具有相同的功能。

但是,您无法摆脱手动处理脚本。您将遇到很多关于预先存在的数据的问题,例如新列的默认值或如何处理重命名/删除/移动列的数据。这只是随着时间的推移使用数据库模式进行分析的一部分,您无法摆脱。如果您尝试使用完全自动化的解决方案来执行此操作,您的数据迟早会变得混乱。

为了让您的生活更轻松,我要推荐的一件事是确保将架构更改与代码更改分开。不同之处在于,对表和列的架构更改必须只运行一次,并且永远不会再次运行,因此必须作为单独的更改脚本进行版本控制。但是,代码更改,例如存储过程、函数,甚至视图,可以(并且应该)一遍又一遍地运行,并且可以像任何其他代码文件一样进行版本控制。我见过的最好的方法是当我们在 VSS 中拥有所有的 procs/functions/views 时,我们的构建过程会在每次更新期间删除所有并重新创建它们。这与重建 C#/Java/任何代码的想法相同,因为它确保所有内容始终是最新的。

【讨论】:

  • @Mike 好点...我处理这个问题的方式一直不一致,希望有一些明显的我遗漏的东西可以让它更容易。我会将您的答案标记为正确并遵循此处的指南,但为了满足我的好奇心并作为备份,我将在单独的答案中发布我为跟踪 DDL 更改而实施的数据库触发器。
  • 如果您在 11g 上,有一个方便的打包函数,称为 dbms_metadata_diff.compare_alter 给它两个对象,它会生成 ALTER 脚本以将一个对象转换为另一个对象。您也可以将其指向数据库链接。
  • @Gary 感谢您的提示...我们还没有使用 11g,但会将其存储起来以备将来使用。
  • “全部重建”方法可能涉及相当长的停机时间,这可能会也可能不会接受。当然,这只影响在存储过程中有数十万 LOC 的系统。
【解决方案2】:

这是我为跟踪 DDL 更改而实施的触发器。使用的来源:

http://www.dba-oracle.com/t_ddl_triggers.htm

http://www.orafaq.com/forum/t/68667/0/

CREATE OR REPLACE TRIGGER ddl_trig
AFTER create OR drop OR alter
  ON scott.SCHEMA
DECLARE
  li ora_name_list_t;
  ddl_text clob;
BEGIN
  for i in 1..ora_sql_txt(li) loop
     ddl_text := ddl_text || li(i);
  end loop;

INSERT INTO my_audit_tbl VALUES
    (SYSDATE,
     ORA_SYSEVENT,
     ORA_DICT_OBJ_TYPE,
     ORA_DICT_OBJ_NAME,
     ddl_text
    );
END;
/

【讨论】:

  • +1 感谢您指出ora_sql_txt。我可能弄错了,但在 FOR 循环中引用 ora_sql_txt 可能会导致函数被多次调用 - 如果只调用一次,它的性能可能会稍好一些。参考这里的例子:docs.oracle.com/cd/B28359_01/appdev.111/b28370/…
【解决方案3】:

切勿将 GUI 用于此类事情。编写脚本并将它们放入源代码管理中。

【讨论】:

    【解决方案4】:

    数据库变更管理/数据库差异 一些工具是——

    1) Oracle 变更管理包

    来自文档 –

    它允许我们在固定时间获取基线(快照),然后我们可以看到数据库架构和对象是如何变化的。 CMP 还可以生成 DDL 脚本,但我不确定我们是否愿意使用它。

    详情

    2) PL/SQL Developer 比较用户对象功能

            This is available from Tools -> Compare User Objects
    

    3) Oracle SQL Developer 数据库差异特性

                This is available from Tools -> Database diff
                http://www.oracle.com/technology/products/database/sql_developer/files/what_is_sqldev.html#copy  See “Schema Copy and Compare”
    



    #1 看起来是最通用和最灵活的,但可能需要 DBA 权限。

    #2 & 3 可以被任何开发者使用。我认为 Oracle SQL Developer 更简单,提供更多选择。

    使用上述任何一个选项都可以帮助 -

    1. 识别更改的对象,也可以在提交 MAC 之前用作检查列表。
    2. 相关开发人员可以拥有特定更改对象的所有权。

    【讨论】:

      【解决方案5】:

      Toad 可以很好地做到这一点。

      您可以使用比较架构功能来查找所有差异(它非常灵活;您可以指定要查看的对象类型以及许多其他选项)。它将向您显示差异,您可以查看并确保它看起来正确,然后告诉它为您生成更新脚本。瞧。唯一的问题是,您需要 DBA 模块来生成同步脚本,这是一个额外的成本。但我会说如果你经常这样做是值得的。 (或者,如果您可以获得旧的 Toad 版本,我认为 9.0 之前的版本,有一个错误允许您在没有 DBA 模块的情况下提取同步脚本。:))

      Toad 并不便宜,但多年来我认为它是必不可少的,对于任何 Oracle 开发人员或 DBA 来说,它都物有所值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-17
        • 2022-06-14
        • 1970-01-01
        • 1970-01-01
        • 2020-02-12
        • 2017-10-23
        • 2021-07-05
        • 1970-01-01
        相关资源
        最近更新 更多