代码之家  ›  专栏  ›  技术社区  ›  batwad

为什么Oracle不为此查询引发“ora-00918:列定义不明确”?

  •  17
  • batwad  · 技术社区  · 14 年前

    我刚刚在Oracle中遇到了一个奇怪的行为,在那里我希望ORA-00918能够被提升,但事实并非如此。

    SELECT *
    FROM USER_TABLES TAB
    JOIN USER_TRIGGERS TRG ON TRG.TABLE_NAME = TAB.TABLE_NAME
    WHERE STATUS = 'DISABLED'
    

    此查询名义上是在查找具有禁用触发器的表的详细信息,但请注意,这不是我要解决的问题。这个问题对于这个查询、数据字典、视图或表不是唯一的;据我所知,它适用于任何一组表或视图(从我尝试过的两个或三个表中)。

    无论如何,试着运行这个查询,你会得到ORA-00918,因为两者都是 USER_TABLES USER_TRIGGERS 有一个列调用 STATUS 所以要让查询运行 WHERE 子句需要更改为 TRG.STATUS . 好的,很酷,但是试着加入另一张桌子。

    SELECT *
    FROM USER_TABLES TAB
    JOIN USER_TRIGGERS TRG ON TRG.TABLE_NAME = TAB.TABLE_NAME
    JOIN USER_CONSTRAINTS CON ON CON.TABLE_NAME = TAB.TABLE_NAME
    WHERE STATUS = 'DISABLED'
    

    这个查询,在不限定您所指的状态列的情况下,非常有效!不要在意语义或查询返回的内容,没有错误。 USER_CONSTRAINTS 甚至有一列名为 状态 同样,当有两列可供选择时,为什么它不知道该怎么做,但它可以接受更多的模糊性呢?

    顺便说一句,这都在10.2.0.3.0上,如果查询中有两个以上的表,那么实际上ORA-00918将停止被提升。如果这是一个Oracle bug,是否有人知道它何时被修复,如果我们的数据库升级,那么哪个Oracle版本可能会导致牛仔查询崩溃?

    更新

    感谢BQ演示了11.2.0.1.0中修复的错误。对任何能在早期版本中显示它的人的赏金!

    5 回复  |  直到 11 年前
        1
  •  8
  •   BQ.    14 年前

    不能说什么时候修好了,但我的结果是:

    Connected to:
    Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
    With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
    Data Mining and Real Application Testing options
    
    SQL> SELECT *
      2  FROM USER_TABLES TAB
      3  JOIN USER_TRIGGERS TRG ON TRG.TABLE_NAME = TAB.TABLE_NAME
      4  WHERE STATUS = 'DISABLED';
    WHERE STATUS = 'DISABLED'
          *
    ERROR at line 4:
    ORA-00918: column ambiguously defined
    
    SQL> ed
    Wrote file afiedt.buf
    
      1  SELECT *
      2  FROM USER_TABLES TAB
      3  JOIN USER_TRIGGERS TRG ON TRG.TABLE_NAME = TAB.TABLE_NAME
      4  JOIN USER_CONSTRAINTS CON ON CON.TABLE_NAME = TAB.TABLE_NAME
      5* WHERE STATUS = 'DISABLED'
    SQL> /
    WHERE STATUS = 'DISABLED'
          *
    ERROR at line 5:
    ORA-00918: column ambiguously defined
    
        2
  •  13
  •   BQ.    14 年前

    搜索了Oracle支持并发现:

    错误5368296-对于不明确的列[ID 5368296.8],ANSI联接SQL可能不会报告ORA-918。

    确认受影响的版本:

    • 10.2.0.3条
    • 10.2.0.4条

    此问题已解决

    • 10.2.0.4 Windows平台上的补丁2
    • 10.2.0.5(服务器补丁集)
    • 11.1.0.6(基本释放)

    由于您需要一个Oracle支持帐户来查看详细信息,因此不会发布更多信息,但您认为受影响的Oracle Bug编号/版本可以共享,从而为您指明Oracle支持的正确方向。

        3
  •  2
  •   erbsock    14 年前

    您使用的是ANSI SQL。我猜想它将WHERE子句中的状态与驾驶台关联起来。

    当您使用“Oracle”语法时,您将看到预期的行为。

    SELECT *
    FROM USER_TABLES TAB, USER_TRIGGERS TRG, USER_CONSTRAINTS CON
    WHERE TRG.TABLE_NAME = TAB.TABLE_NAME
    AND CON.TABLE_NAME = TAB.TABLE_NAME
    AND STATUS = 'DISABLED'
    
        4
  •  1
  •   Sebastien Tardif    12 年前

    有关此问题的更多确认错误: http://oracledoug.com/serendipity/index.php?/archives/1555-Bug-Hunting.html

    最新更新是在11.2.0.2中修复的

        5
  •  0
  •   Jan Snelders    11 年前

    好吧,如果我在11.2.0.2.0上尝试这个,我会得到同样的问题。不管功能如何,如果您添加了一些左连接和右连接,这个bug似乎根本没有被修复!

    SELECT *
    FROM USER_TABLES TAB
    LEFT JOIN USER_TRIGGERS TRG ON TRG.TABLE_NAME = TAB.TABLE_NAME
    RIGHT JOIN USER_CONSTRAINTS CON ON CON.TABLE_NAME = TAB.TABLE_NAME
    WHERE STATUS = 'DISABLED'