Почему Oracle не вызывает "Ora-00918: столбец неоднозначно определен" для этого запроса?

Я только что столкнулся со странным поведением в 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 даже есть столбец под названием STATUS кроме того, почему он не знает, что делать, когда есть два столбца на выбор, но это нормально с еще большей двусмысленностью?

это все на 10.2.0.3.0 кстати, и по сути ORA-00918 перестает быть поднятым, если у вас есть более двух таблиц в вашем запросе. Если это ошибка Oracle, кто-нибудь знает, когда она была исправлена, и поэтому какая версия Oracle, вероятно, вызовет ковбойские запросы, чтобы взорвать, если наша база данных повышен?

обновление

благодаря BQ для демонстрации ошибка исправлена в 11.2.0.1.0. Bounty для тех, кто может показать его исправлено в более ранней версии!

5 ответов


Не могу сказать, когда это было исправлено, но мои результаты вот:

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

поиск поддержки Oracle и нашел это:

ошибка 5368296-ANSI join SQL не может сообщить ORA-918 для неоднозначного столбца [ID 5368296.8]

версии подтверждены как затронутые:

  • 10.2.0.3
  • 10.2.0.4

эта проблема исправлена в

  • 10.2.0.4 патч 2 на платформах Windows
  • 10.2.0.5 (Патч-Сервер)
  • 11.1.0.6 (Базовый Релиз)

Не публикация больше, чем это, так как вам нужна учетная запись поддержки Oracle для просмотра деталей, но думал, что номер ошибки Oracle/версии затронуты будет нормально Поделиться, чтобы указать вам в правильном направлении на поддержку Oracle.


вы используете 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'

более подтвержденная ошибка об этом здесь:http://oracledoug.com/serendipity/index.php?/archives/1555-Bug-Hunting.html

последнем обновлении это исправлено в 11.2.0.2


Ну, если я попробую это на 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'