重新编译Oracle包是安全的

时间:2010-09-29 16:50:54

标签: oracle plsql packages

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

重新编译没有副作用的安全操作吗?

4 个答案:

答案 0 :(得分:3)

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

您正在寻找的错误是“ORA-04068:已丢弃现有的包状态”。

有关详细信息,请参阅here

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

答案 1 :(得分:3)

就个人而言,我会避免“重新编译全部”(在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)发送回来的进展很有用。 Ora 10)。

我的作业递归尝试使用以下SQL编译所有依赖项为VALID的INVALID对象,直到迭代之间没有变化。

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'

答案 2 :(得分:2)

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

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

答案 3 :(得分:2)

如果你的软件包无效,那么它们实际上是无效的,因为它们将不再起作用了吗? 尝试使用sqlplus重新编译无效的包体。

SQL>alter package <package name> compile body;

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

SQL>show errors;

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

一般来说,重新编译包裹的包很好。应该不是问题。