Почему Oracle не сообщает вам, КАКОЙ таблицы или представления не существует? - PullRequest
59 голосов
/ 05 сентября 2008

Если вы использовали Oracle, вы, вероятно, получили полезное сообщение «ORA-00942: Таблица или представление не существует». Существует ли законная техническая причина, по которой сообщение не содержит названия пропавшего объекта?

Аргументы в пользу того, что это из-за безопасности, звучат так, будто они были созданы TSA. Если я нападающий, я буду знать, какую таблицу я только что попытался использовать, и смогу легко интерпретировать это бесполезное сообщение. Если я разработчик, работающий со сложным соединением через несколько уровней кода приложения, это часто очень трудно сказать.

Я предполагаю, что когда эта ошибка была изначально реализована, кто-то пренебрег добавлением имени объекта, и теперь люди боятся, что это нарушит совместимость, чтобы исправить это. (Код, выполняющий глупые вещи, такие как анализ сообщения об ошибке, будет сбит с толку, если он изменится.)

Существует ли удобный для разработчиков (в отличие от рекрутинга вашего администратора БД) способ определения имени отсутствующей таблицы?


Хотя я принял ответ, который имеет отношение к теме, он на самом деле не отвечает на мой вопрос: Почему это не часть имени в сообщении об ошибке? Если кто-то может придумать реальный ответ, я буду рад изменить свой голос.

Ответы [ 8 ]

13 голосов
/ 05 сентября 2008

Вы можете установить СОБЫТИЕ в вашем файле параметров (обычный текст или spfile), чтобы заставить Oracle сбросить файл подробной трассировки в user_dump_dest, имя объекта может быть там, если не SQL должен быть.

EVENT = "942 уровень трассировки ошибок имен трасс 12"

Если вы используете простой текстовый файл, вам нужно сохранять все настройки EVENT в последовательных строках. Не уверен, как это относится к spfile.

12 голосов
/ 09 сентября 2008

SQL * Plus говорит вам, что таблица не существует. Например:

SQL> select
  2     *
  3  from
  4     user_tables a,
  5     non_existent_table b
  6  where
  7     a.table_name = b.table_name;
   non_existent_table b
   *
ERROR at line 5:
ORA-00942: table or view does not exist

Здесь показано, что имя отсутствующей таблицы и номер строки в операторе SQL, где происходит ошибка.

Аналогичным образом, в однострочном SQL-выражении вы можете увидеть звездочку с именем неизвестной таблицы:

SQL> select * from user_tables a, non_existent_table b where a.table_name = b.table_name;
select * from user_tables a, non_existent_table b where a.table_name = b.table_name
                             *
ERROR at line 1:
ORA-00942: table or view does not exist

С точки зрения вашего вопроса, я думаю, причина того, что сообщение об ошибке не содержит названия таблицы, состоит в том, что само сообщение об ошибке должно быть статическим текстом. Номер строки и расположение в строке ошибки явно передаются обратно в SQL * Plus (как-то).

5 голосов
/ 31 января 2011

Я бы не согласился с мнением, что SQL + позволяет понять, какое имя таблицы недопустимо. Правда, это помогает в прямом DML, хотя разбирать его очень сложно. Но когда дело доходит до динамики, мы не получаем никакой помощи:

SQL> begin
  2  execute immediate 'insert into blabla values(1)';
  3  end;
  4  /
begin
*
ERROR at line 1:
ORA-00942: table or view does not exist
ORA-06512: at line 2
5 голосов
/ 05 сентября 2008

Если вы используете инструмент просмотра SQL, такой как TOAD или TORA, он поможет вам с ошибками ORA, выделив или наведя курсор на то место, где вы сделали ошибку.

Скопируйте и вставьте свой SQL в один из этих инструментов, чтобы помочь. Также вам может пригодиться информация для анализа.

4 голосов
/ 21 апреля 2009

У меня никогда не было проблем с интерпретацией сообщений об ошибках Oracle. Частично причина в том, что каждый интерактивный инструмент, который я видел для разработки SQL для Oracle, указывает на местоположение, в котором произошел сбой запроса. Это включает в себя SQL * Plus, как отмечали другие, и модуль Perl DBI:

$ exec_sql.pl 'select * from daul'
DBD::Oracle::db prepare failed: ORA-00942: table or view does not exist (DBD ERROR: error possibly near <*> indicator at char 14 in 'select * from <*>daul') [for Statement "select * from daul"] at exec_sql.pl line 68.

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

Чтобы ответить на основной вопрос, кажется, что ошибки Oracle не предназначены для того, чтобы работать так, как вы ожидаете. Насколько я могу судить, ни одно из сообщений об ошибках в Oracle не поддерживает переменную text. Вместо этого Oracle возвращает два бита информации: номер ошибки и место, где происходит ошибка. Если у вас есть надлежащие инструменты, диагностировать ошибку по этим частям довольно легко. Можно утверждать, что система Oracle лучше для создателей инструментов, чем система, которая предоставляет переменные объемы диагностических данных в зависимости от ошибки. Представьте себе, что вам нужно написать собственный синтаксический анализатор для всех сообщений об ошибках Oracle (включая будущие ошибки), чтобы выделить ошибочное местоположение.

Иногда включение имени таблицы может вводить в заблуждение. Просто знание, где что-то пошло не так, может быть огромной помощью:

SQL> select * from where dummy = 'X';
select * from where dummy = 'X'
              *
ERROR at line 1:
ORA-00903: invalid table name

Что касается того, почему Oracle решил так поступить, у меня есть некоторые предположения:

  1. IBM использовала этот стиль сообщения об ошибке для System R, который Ларри Эллисон, Боб Майнер и Эд Оутс скопировали для создания Oracle V2. (Обратная совместимость.)

  2. Номер и местоположение ошибки - это наименьшее возможное представление диагностической информации. (Скупость.)

  3. Как я указывал выше, для упрощения создания инструментов, подключающихся к Oracle. (Interoperability.)

В любом случае, я не думаю, что вам нужно быть администратором баз данных, чтобы выяснить, какой таблицы не существует. Вам просто нужно использовать соответствующие инструменты. (И скорректируйте свои ожидания, я полагаю.)

3 голосов
/ 21 апреля 2009

Причина 1: многоязычный интерфейс

Для вашего экземпляра базы данных существует файл конфигурации сообщений для конкретного языка. Сообщения извлекаются оттуда и переводятся из чисто числовой версии в числовую + текстовую версию.

Вероятно, считалось, что лучше иметь жестко закодированные строки, чем рисковать во время выполнения иметь загадочный сбой из-за неправильно отформатированной строки "% s".

(Не то чтобы я особенно согласен с этим POV, кстати)

Причина 2: безопасность

Прямо сейчас вы не особенно раскрываете внутреннюю работу вашего приложения, если вы печатаете PHP и т. Д., Дамп сообщения об ошибке Oracle в браузер.

Приложения были бы немного более открытыми, если бы по умолчанию печаталось больше деталей ... Например, если Ситибанк напечатал более пояснительное сообщение.

(см. Отказ от ответственности выше, я также был бы рад получить дополнительную информацию об ошибке.)

3 голосов
/ 06 сентября 2008

Если это не большое утверждение, то самый простой способ - просто проверить словарь данных,

SQL> select * from xx,abc;
select * from xx,abc
                 *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> select owner,table_name from all_tables where table_name in ('XX','ABC');

OWNER                          TABLE_NAME
------------------------------ ------------------------------
MWATSON                        XX

SQL> 

Это не идеально, но если не рассматривать и изучать файлы трассировки, я не уверен, как еще это сделать.

1 голос
/ 07 сентября 2008

@ Мэтью

Ваш запрос является началом, но он может не работать, если у вас несколько схем. Например, если я войду в наш экземпляр как я, у меня будет доступ на чтение ко всем нашим таблицам. Но если я не укажу имя таблицы схемой, я получу ORA-00942 для таблиц без синонимов:

SQL> select * from tools; 
select * from tools 
              * 
ERROR at line 1: 
ORA-00942: table or view does not exist 

Таблица все еще отображается во всех таблицах:

SQL> select owner, table_name from all_tables where table_name = 'TOOLS'; 

OWNER                          TABLE_NAME 
------------------------------ ------------------------------ 
APPLICATION                    TOOLS 

@ Эриксон Извините, это не очень помогает. Я с Марком - я использовал TOAD.

...