【问题标题】:Oracle AQ Enqueue Default SchemaOracle AQ Enqueue 默认模式
【发布时间】:2014-05-19 14:11:09
【问题描述】:

从关于 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

【问题讨论】:

    标签: oracle advanced-queuing


    【解决方案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' 作为队列名称传递。

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 有什么原因不能在队列名称前加上模式?你是从另一个存储过程中调用它,还是临时调用它?
      猜你喜欢
      • 2011-01-22
      • 2011-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-17
      • 1970-01-01
      相关资源
      最近更新 更多