1

从关于 DBMS_AQ 的入队方法的 Oracle 文档中,指定“对象的名称由可选的模式名称和名称指定。如果未指定模式名称,则假定当前模式。” [1]

有问题的系统定义了模式中的所有对象,我们称之为 DEV。然后像 DEV_AD 一样定义用户,并且在登录期间,有一个触发器将其当前模式更改为 DEV。这意味着当他们从某个表中选择 * 时,他们从 DEV.sometable 中选择 *,而不是 DEV_AD.sometable。这没有任何问题。

但是,当用户尝试在 SOMEQUEUE 上排队消息时,它不起作用 - 系统尝试在不存在的 DEV_AD.SOMEQUEUE 上排队,而不是在 DEV.SOMEQUEUE 上排队。通过将 DEV.SOMEQUEUE 而不仅仅是 SOMEQUEUE 作为 DBMS_AQ.ENQUEUE 的参数,消息成功排队。

这是一个 Oracle 错误(或文档错误),是否有解决方法?

如果这是一个错误,我们在接下来的几个月里仍然使用 10.2.0.4.0。是固定在11g吗?

[1] http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_aq.htm#ARPLS081

4

2 回答 2

1

在进一步寻找 Oracle 支持之后,这是一个错误 - 请参阅 Metalink 中的 Doc ID 220477.1。

它已在 11.2.0.2 中修复;此公共链接包含更多信息:https ://community.oracle.com/thread/846141但修复对我们不起作用。

于 2014-05-20T06:50:11.037 回答
1

鉴于这是错误 1259821 并且事件解决方法对您不起作用或不实际实施,您的另一个选择是通过指定架构名称来完全限定队列名称。大概您正在尝试避免在 AQ 调用中对架构名称进行硬编码,例如:

dbms_aq.enqueue(queue_name => 'DEV.SOMEQUEUE', ...);

...因为您有跨环境共享的公共代码,并且您希望根据登录触发器设置的架构在运行时使用正确的架构/队列。

如果是这种情况,那么您可以使用当前模式来指定完整的队列名称:

dbms_aq.enqueue(queue_name =>
  sys_context('USERENV', 'CURRENT_SCHEMA') || '.SOMEQUEUE', ...);

在运行时,对于您的DEV_AD用户,它仍将'DEV.SOMEQUEUE'作为队列名称传递。

这在即席代码中有点痛苦(如果您从匿名块调用),但如果您从存储过程排队,那也不算太糟糕。从错误描述来看,这似乎只是存储代码中的一个问题,因为定义者/调用者权限与匿名块无关。

于 2014-05-20T09:33:38.500 回答