Почему Oracle не сообщает вам, какой таблицы или представления не существует?

53

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

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

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

Есть ли способ, подходящий для разработчиков (в отличие от набора вашего DBA), чтобы определить имя отсутствующей таблицы?


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

  • 1
    Я полагаю, вам нужно попросить настоящего инженера Oracle получить реальный ответ. Между прочим, я работаю на Sybase, и наш сервер (SQL Anywhere) выдает «Таблица« бла »не найдена».
  • 3
    Это может быть связано с нераскрытием рефлекса;): ссылка
Показать ещё 1 комментарий
Теги:
database
ora-00942

8 ответов

13
Лучший ответ

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

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

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

  • 0
    Я попытался добавить эту строку в файл «init.ora», а затем перезапустил мою базу данных, но в папке user_dump_dest ничего не было доступно. Любые советы, пожалуйста?
13

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
    Это нормально, когда вы можете использовать SQL * Plus в интерактивном режиме для проверки ваших запросов. Однако наиболее распространенным случаем является случай, когда у вас есть журнал только из приложения, использующего постоянный уровень, такой как Hibernate, и трудно точно определить, какой запрос мог быть выполнен.
  • 2
    @erickson: это больше проблемы с Hibernate;) (шучу)
Показать ещё 2 комментария
5

Я бы не согласился с мнением, что 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

У меня никогда не возникало проблем с интерпретацией сообщений об ошибках 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.

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

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

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

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

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

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

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

  • Как я указал выше, упростить создание инструментов, которые подключаются к Oracle. (Совместимость).

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

  • 1
    Спасибо за вклад, Джон. Я не прояснил это, но в моем случае они обычно встречаются в приложениях Java через несколько различных уровней кода: веб-инфраструктуру, постоянную библиотеку, драйвер базы данных Java. Поэтому иногда бывает трудно даже определить, какой запрос выполнялся, особенно если вы работаете с другой группой, чтобы получить журналы, созданные во время тестирования третьей группой! Да, это настоящая бочка обезьян.
  • 0
    Я бы сказал, что это больше обвинение Java, чем Oracle. ;-)
Показать ещё 4 комментария
5

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

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

  • 0
    Ну, для меня это выделение константы, которую я определил, например, ": myvar", так что тогда никакой помощи
4

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

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> 

Это не идеально, но, не дожидаясь рассмотрения и проверки файлов трассировки, я не уверен, как это сделать.

3

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

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

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

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

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

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

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

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

2

@Matthew

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

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

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

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню