【问题标题】:Is recompiling Oracle Packages safe重新编译 Oracle 包是否安全
【发布时间】:2011-04-18 22:41:01
【问题描述】:

嗨 我们有一个第三方基于 oracle 的应用程序,它附带预编译的二进制(包装)包。 但是当我在 Oracle SQL Developer 中编译它们时(右键单击 -> 全部编译),它们就会失效。

重新编译是否安全且无副作用的操作?

【问题讨论】:

  • 不是真的——除非你知道它是如何编译的。这是一个问题 - 如果它有效,你为什么要编译它?

标签: oracle plsql packages


【解决方案1】:

大多数第三方应用程序建议您不要编辑/编译他们的对象,除非他们的支持当然告诉您这样做。

由于你不知道所有的依赖对象,我建议你在修改他们的对象之前先联系第三方应用程序的支持团队。如果它是捆绑应用程序,简单地重新编译 oracle 对象可能会使其他层中的依赖应用程序/服务无效。

【讨论】:

    【解决方案2】:

    主要的副作用是,如果您编译另一个包所依赖的包,则可能会使任何现有会话的依赖包无效——即使编译没有错误。这对于会话短暂的应用程序来说很好,但对于会话长期存在的应用程序来说,这是一个问题。如果您在 JDBC 中使用连接池,则缓存的会话将长期存在并且可能会失效。您必须刷新缓存的会话以避免错误。

    您要查找的错误是“ORA-04068: 包的现有状态已被丢弃”。

    请参阅here 了解更多信息。

    特别是关于 SQL Developer - 它不能很好地处理包装包的重新编译。如果您要重新编译它们,请尝试使用其他工具,如 TOAD 或 PL/SQL Developer,或使用 SQL Plus 命令行中的“alter package”命令。

    【讨论】:

      【解决方案3】:

      如果您的软件包无效,它们是否真的无效,因为它们将不再工作? 尝试使用 sqlplus 重新编译无效的包体。

      SQL>alter package <package name> compile body;
      

      如果您收到“编译错误”的消息

      SQL>show errors;
      

      这将提供有关错误的一些信息。

      一般来说,重新编译包装好的包是可以的。应该不是问题。

      【讨论】:

        【解决方案4】:

        就我个人而言,我会避免“重新编译所有”(在 SQL Developer 或 TOAD 中)——尤其是在您从其他用户或软件打开数据库连接的任何环境中。

        在大多数情况下,您可能只想重新编译无效对象。

        如果您使用的是 Oracle 10 或更高版本,则有两个内置软件包可以执行此操作(尽管您的角色可能无法在不与您的 DBA 交谈的情况下访问它们)。

        UTL_RECOMP.RECOMP_PARALLEL(threads => 4, schema => :schema_owner)
        
        DBMS_UTILITY.COMPILE_SCHEMA(schema => :schema_owner, compile_all => FALSE)
        

        UTL_RECOMP 是新的首选方式。 DBMS_UTILITY 存在于早期版本的 Oracle 中,但总是会编译所有内容 - compile_all 是一个新的可选标志,它让我们告诉它只编译无效项。

        如果您使用的是早于 10 的版本,我建议您使用自己的编译无效程序 - 我发现将其编写为可以通过 DBMS_JOB 提交的作业,然后通过 DBMS_SMTP(DBMS_MAIL 在奥拉 10)。

        我的工作递归地尝试编译所有依赖项都有效的无效对象,使用以下 SQL,直到迭代之间没有更改。

        SELECT  uo.object_name,uo.object_type
        FROM    user_objects uo
        WHERE   uo.status = 'INVALID'
        MINUS   -- objects with invalid children
        SELECT  uo.object_name,uo.object_type
        FROM    user_objects uo,
            user_objects uo2,
            public_dependency pd
        WHERE   uo.status = 'INVALID'
        AND     uo.object_id =  pd.object_id
        AND     pd.referenced_object_id =  uo2.object_id
        AND       uo2.status = 'INVALID'
        

        【讨论】:

        • In : UTL_RECOMP.RECOMP_PARALLEL(threads => 4, schema => :schema_owner) 你怎么能限制为无效。
        • UTL_RECOMP 只对 INVALID 对象进行操作 - 这是它与 DBMS_UTILITY.COMPILE_SCHEMA 的主要区别。
        猜你喜欢
        • 2016-04-21
        • 1970-01-01
        • 1970-01-01
        • 2020-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-30
        • 1970-01-01
        相关资源
        最近更新 更多