Ошибка ORA-00942: table or view does not exist в Oracle DB — решение
- Ошибка
ORA-00942: table or view does not existпри выполнении запроса или компиляции хранимой процедуры. - Приложение подключается к базе, но не видит объекты бизнес-схемы.
- Пользователь видит таблицу в DBeaver/PLSQL Developer, но процедура падает с ORA-00942 при вызове.
1. Проверка существования объекта в базе данных
SELECT owner, object_name, object_type, status
FROM all_objects
WHERE object_name = UPPER('MY_TABLE');2. Проверка и выдача прав доступа (Grants)
Даже если таблица существует в другой схеме, отсутствие прав SELECT/INSERT/UPDATE вернет именно ORA-00942 (в целях безопасности СУБД скрывает факт существования объекта):
-- Выполняется владельцем схемы (SCHEMA_OWNER) или DBA
GRANT SELECT, INSERT, UPDATE, DELETE ON SCHEMA_OWNER.MY_TABLE TO APP_USER;3. Создание синонима для работы без префикса схемы
-- Создание приватного синонима для пользователя
CREATE OR REPLACE SYNONYM APP_USER.MY_TABLE FOR SCHEMA_OWNER.MY_TABLE;
-- Или создание публичного синонима (для всех пользователей базы)
CREATE OR REPLACE PUBLIC SYNONYM MY_TABLE FOR SCHEMA_OWNER.MY_TABLE;4. Специфика хранимых процедур (Роли vs Прямые привилегии)
В хранимых процедурах с правами создателя (AUTHID DEFINER — по умолчанию) права, выданные через РОЛИ (Roles), не действуют! Привилегии на таблицы должны быть выданы напрямую пользователю:
-- Не сработает внутри процедуры: GRANT MY_ROLE TO APP_USER;
-- Сработает:
GRANT SELECT ON SCHEMA_OWNER.MY_TABLE TO APP_USER; Частые вопросы (FAQ)
Почему пользователь может делать SELECT к таблице вручную, но хранимая процедура падает с ORA-00942?
В интерактивной сессии действуют привилегии, полученные через роли. Внутри хранимого PL/SQL пакета (с AUTHID DEFINER) роли отключаются, требуются прямые гранты (Direct Grants).
Как переключить процедуру на использование прав вызывающего пользователя?
Добавьте конструкцию AUTHID CURRENT_USER в заголовок пакета/процедуры (Invoker's Rights). Тогда внутри будут действовать роли текущей активной сессии.
Почему Oracle возвращает 'table does not exist' вместо 'insufficient privileges'?
Это фундаментальный принцип безопасности Oracle. Если бы СУБД сообщала 'недостаточно прав', злоумышленник мог бы перебором имен узнать структуру секретных таблиц системы.
Как автоматически перенаправлять запросы к нужной схеме без синонимов?
Выполните в начале сессии команду ALTER SESSION SET CURRENT_SCHEMA = target_schema;. Это избавит от необходимости писать имя схемы перед каждой таблицей.