Подтвердить что ты не робот

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

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

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

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

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


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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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 (как-то).

Ответ 3

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

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

Ответ 4

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

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

Ответ 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

Ответ 6

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

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> 

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

Ответ 7

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

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

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

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

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

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

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

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

Ответ 8

@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.