重新编译 Oracle 包是否安全
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3823932/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is recompiling Oracle Packages safe
提问by vamsi-vegi
Hi We have a third party oracle based application, that ships with precompiled binary(wrapped) packages. But when I compile them in Oracle SQL Developer (right click -> compile all), they get invalidated.
嗨,我们有一个基于 oracle 的第三方应用程序,它带有预编译的二进制(包装)包。但是当我在 Oracle SQL Developer 中编译它们(右键单击 -> 编译全部)时,它们会失效。
Is recompiling a safe operation with no side effects?
重新编译是一个没有副作用的安全操作吗?
回答by darreljnz
The major side effect is that if you compile a package which another package is dependant upon you risk invalidating the dependant package for any existing sessions - even if the compile has no errors. This is fine for applications where sessions are short-lived but for applications where sessions are long-lived this is a problem. If you're using connection pools in JDBC the cached sessions will be long lived and likely invalidated. You have to flush the cached sessions to avoid the error.
主要的副作用是,如果您编译另一个包所依赖的包,您可能会使任何现有会话的依赖包无效 - 即使编译没有错误。这对于会话短暂的应用程序很好,但对于会话长期存在的应用程序这是一个问题。如果您在 JDBC 中使用连接池,则缓存的会话将长期存在并且可能会失效。您必须刷新缓存的会话以避免错误。
The error you're looking for is "ORA-04068: existing state of packages has been discarded".
您要查找的错误是“ORA-04068:包的现有状态已被丢弃”。
See herefor more info.
请参阅此处了解更多信息。
Specifically with regards to SQL Developer - it does not handle recompilation of wrapped packages well. If you are going to recompile them try another tool like TOAD or PL/SQL Developer or use the "alter package" command in the SQL Plus command line.
特别是关于 SQL Developer - 它不能很好地处理包装包的重新编译。如果您要重新编译它们,请尝试使用其他工具,例如 TOAD 或 PL/SQL Developer,或者使用 SQL Plus 命令行中的“alter package”命令。
回答by JulesLt
Personally, I'd avoid 'Recompile All' (in SQL Developer or TOAD) - especially in any environment where you have open database connections from other users or software.
就个人而言,我会避免“全部重新编译”(在 SQL Developer 或 TOAD 中)——尤其是在您拥有来自其他用户或软件的开放数据库连接的任何环境中。
In most situations you probably just want to recompile Invalid objects.
在大多数情况下,您可能只想重新编译无效对象。
If you're on Oracle 10 or above, there are two in-built packages that will do this (although they may not be accessible to your role without speaking to your DBA).
如果您使用的是 Oracle 10 或更高版本,则有两个内置程序包可以执行此操作(尽管您的角色可能无法在不与您的 DBA 交谈的情况下访问它们)。
UTL_RECOMP.RECOMP_PARALLEL(threads => 4, schema => :schema_owner)
DBMS_UTILITY.COMPILE_SCHEMA(schema => :schema_owner, compile_all => FALSE)
UTL_RECOMP is the new preferred way to do it. DBMS_UTILITY exists on earlier versions of Oracle, but would always compile everything - compile_all is a new optional flag, that lets us tell it to compile only invalid items.
UTL_RECOMP 是新的首选方式。DBMS_UTILITY 存在于 Oracle 的早期版本中,但总是会编译所有内容 - compile_all 是一个新的可选标志,它让我们告诉它只编译无效项目。
If you are on an earlier version than 10, I'd suggest rolling your own compile invalid procedure - I found it useful to write this as a job that can be submitted via DBMS_JOB and then emails back progress via DBMS_SMTP (DBMS_MAIL in Ora 10).
如果您使用的是 10 之前的版本,我建议您滚动自己的编译无效程序 - 我发现将其编写为可以通过 DBMS_JOB 提交的作业,然后通过 DBMS_SMTP(Ora 10 中的 DBMS_MAIL)通过电子邮件发送进度很有用.
My job recursively tries to compile INVALID objects where all dependencies are VALID, using the following SQL, until there are no changes between iterations.
我的工作递归地尝试编译所有依赖项都有效的 INVALID 对象,使用以下 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'
回答by Rene
If your packages get invalid are they actually invalid in the sense that they won't work anymore? Try to recompile an invalid package body using sqlplus.
如果您的软件包无效,它们实际上是否无效,因为它们将不再起作用?尝试使用 sqlplus 重新编译无效的包体。
SQL>alter package <package name> compile body;
If you get the message "compiled with errors"
如果您收到消息“编译有错误”
SQL>show errors;
This will give some information about the error.
这将提供有关错误的一些信息。
Generally speaking it is fine to recompile wrapped packages. Should not be a problem.
一般来说,重新编译打包的包是可以的。应该没有问题。
回答by Rajesh Chamarthi
Most third party applications advice you against editing/compiling their objects unless of course their support tells you to do so.
大多数第三方应用程序建议您不要编辑/编译他们的对象,除非他们的支持告诉您这样做。
Since you do not know all the dependent objects, I would suggest you contact the third-part application's support team first before modifying their objects. If it is a bundled application, simply recompiling oracle objects may leave dependent applications/services in other tiers invalid.
由于您不了解所有依赖对象,我建议您在修改其对象之前先联系第三方应用程序的支持团队。如果是捆绑应用程序,简单地重新编译 oracle 对象可能会使其他层中的依赖应用程序/服务无效。