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


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

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

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

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


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

8 57

8 ответов:

вы можете установить событие в файле параметров (обычный текст или spfile), чтобы заставить Oracle сбросить подробный файл трассировки в user_dump_dest, имя объекта может быть там, если не SQL должен быть.

EVENT= "942 имя трассировки errorstack Уровень 12"

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

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 (каким-то образом).

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

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

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

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

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

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

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

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

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

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: многоязычный интерфейс

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

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

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

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

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

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

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

@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 Жаль, что это не очень помогает. Я с Марком-я раньше жаба.