17

我刚刚在 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一个名为STATUSso 的列,以便让查询运行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'

这个查询,没有限定你的意思是哪个 STATUS 列,神奇地工作!不用管语义或查询返回的内容,没有错误。 USER_CONSTRAINTS甚至还有一个名为的列STATUS,那么为什么当有两列可供选择时它不知道该怎么做,但如果有更多的歧义也没关系?

顺便说一句,这一切都在 10.2.0.3.0 上,如果您的查询中有两个以上的表,则本质上会停止引发 ORA-00918。如果这是一个 Oracle 错误,有谁知道它是什么时候修复的,那么如果我们的数据库升级,哪个 Oracle 版本可能会导致牛仔查询崩溃?

更新

感谢 BQ 证明该错误已在 11.2.0.1.0 中修复。任何可以在早期版本中修复它的人的赏金!

4

5 回答 5

13

搜索了 Oracle 支持,发现了这个:

错误 5368296 - ANSI 连接 SQL 可能不会为不明确的列报告 ORA-918 [ID 5368296.8]

确认受影响的版本:

  • 10.2.0.3
  • 10.2.0.4

此问题已修复

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

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

于 2010-11-29T17:38:31.330 回答
8

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

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
于 2010-11-24T16:53:03.747 回答
2

您正在使用 ANSI SQL。我猜测它将where子句中的STATUS与驱动表相关联。

当您使用“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'
于 2010-11-24T16:52:21.327 回答
1

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

最新更新是在 11.2.0.2 中修复

于 2012-02-28T16:57:12.160 回答
0

好吧,如果我在 11.2.0.2.0 上尝试这个,我会遇到同样的问题。不管功能如何,如果你添加一些左右连接,这个错误似乎根本无法修复!

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'
于 2013-11-07T14:16:13.020 回答