有啥方法可以确定包在 Oracle 中是不是有状态?
Posted
技术标签:
【中文标题】有啥方法可以确定包在 Oracle 中是不是有状态?【英文标题】:Is there any way to determine if a package has state in Oracle?有什么方法可以确定包在 Oracle 中是否有状态? 【发布时间】:2012-06-18 01:17:19 【问题描述】:Oracle 中有没有办法确定一个包是有状态还是无状态?我不知道包含该信息的数据字典中的任何视图。
“ORA-04068:包字符串的现有状态已被丢弃”错误相当烦人。它可以通过从包中删除包变量来消除。 11g 引入了一个特性,一个包含所有编译时常量的变量的包将被视为无状态。
我可以有两个会话,在一个会话中编译包并在另一个中调用它,看看它是否引发异常,但这需要调用包中的一个过程,这可能是不可取的。
【问题讨论】:
在我回答之前,你能解释一下你为什么想知道吗?不要试图成为一个痛苦,只是试图了解你到底想做什么。为什么知道包是否有状态对您很重要?此外,您是否只是想知道一个包是否有状态,因此是否可能在某个时候遇到 ORA-4068?或者,对于有状态的包,您是否有兴趣了解包的当前状态是有效、无效还是未初始化? 有状态的包可能很烦人,因为如果在会话打开时进行更改,可能会导致用户出错。我有一个包有这个问题,我正在重构它以使其成为无状态并遇到一些麻烦(这将是未来 SO 问题的主题),所以有一种简单的方法来判断包是无状态的还是不是。此外,数据库中的哪些其他包是有状态的,也可能导致此问题。 【参考方案1】:听起来你想要的是能够列出所有可能有状态的包。
您正在寻找的只是具有任何全局变量或常量的包。对于单个包装,这通过检查非常简单。但是,要查看模式中的所有包,您可以使用 PL/Scope:
首先,以架构所有者身份登录,在会话中打开 PL/Scope:
alter session set plscope_settings='IDENTIFIERS:ALL';
然后,重新编译所有包体。
然后,运行此查询以查找在包级别声明的所有变量和常量:
select object_name AS package,
type,
name AS variable_name
from user_identifiers
where object_type IN ('PACKAGE','PACKAGE BODY')
and usage = 'DECLARATION'
and type in ('VARIABLE','CONSTANT')
and usage_context_id in (
select usage_id
from user_identifiers
where type = 'PACKAGE'
);
我建议你的目标是生成的包列表。
如果您使用的是 11gR2,则常量不再导致此问题,因此您可以改用此查询:
select object_name AS package,
type,
name AS variable_name
from user_identifiers
where object_type IN ('PACKAGE','PACKAGE BODY')
and usage = 'DECLARATION'
and type = 'VARIABLE'
and usage_context_id in (
select usage_id
from user_identifiers
where type = 'PACKAGE'
);
【讨论】:
这不是我想要的。在 11g 中,包含所有CONSTANT
包变量的包被认为是无状态的,但您的查询将返回它们。
eaolson,这不太正确。在 11gR1 中,常量 do 使包具有状态;这在 11gR2 中已修复。我已编辑问题以说明这一点。
我认为当用户模式中存在更多包时选择存在问题,因此应将子选择扩展到AND usage_context_id IN (SELECT usage_id FROM user_identifiers i2 WHERE TYPE = 'PACKAGE' AND i2.object_name = i.object_name)
注意加入 AND i2.object_name = i.object_name 最后,并且父 select 中的 user_identifiers 必须是别名 i。但是还是很好的答案!
谢谢@GWu,你可能是对的。我根据一个小的测试模式组成了这些查询。根据文档,user_identifiers.usage_id
在对象中是唯一的。以上是关于有啥方法可以确定包在 Oracle 中是不是有状态?的主要内容,如果未能解决你的问题,请参考以下文章
我们可以使用任何其他数据库,如 MariaDB 或 MongoDB 来在 Kafka Streams 中存储状态而不是 Rocks DB,有啥方法可以配置它吗?