ORA-00942: таблица или представление не существует (работает, когда отдельный sql, но не работает внутри функции oracle)
когда у меня есть оператор sql, например select * from table1
, он отлично работает, но как только я помещаю его в функцию, я получаю:
ORA-00942: table or view does not exist
Как это решить?
5 ответов
есть несколько вещей, которые вы могли бы посмотреть. Основываясь на вашем вопросе, похоже, что владелец функции отличается от владельца таблицы.
1) предоставляет через роль: для создания хранимых процедур и функций на объектах другого пользователя требуется прямой доступ к объектам (вместо доступа через роль).
2)
по умолчанию хранимые процедуры и методы SQL выполняются с помощью привилегии их владельца, а не их текущий пользователь.
Если вы создали таблицу в схеме A и функцию в схеме B, вы должны взглянуть на концепции прав вызывающего/Определителя Oracle, чтобы понять, что может вызвать проблему.
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/subprograms.htm#LNPLS00809
существует большая вероятность того, что привилегии для выбора из таблицы 1 были предоставлены роли, и роль была предоставлена вам. Права, предоставленные роли, недоступны для PL / SQL, написанного пользователем, даже если пользователю была предоставлена роль.
вы видите это много для пользователей, которым была предоставлена роль dba для объектов, принадлежащих sys. Пользователь с ролью dba сможет, скажем,SELECT * from V$SESSION
, но не сможет написать функцию, которая включает SELECT * FROM V$SESSION
.
исправление заключается в предоставлении явных разрешений на рассматриваемый объект непосредственно пользователю, например, в случае выше, пользователь SYS должен GRANT SELECT ON V_$SESSION TO MyUser;
либо у вас нет разрешения на эту схему / таблицу, либо таблица существует. В основном эта проблема возникает при использовании других таблиц схемы в хранимых процедурах. Например. Если вы используете хранимую процедуру из user/schema ABC и в том же PL/SQL есть таблицы, которые из user / schema XYZ. В этом случае ABC должна иметь GRANT т. е. привилегии таблиц XYZ
предоставить все на ABC;
Select * From Dba_Tab_Privs Where Owner = 'XYZ'and Table_Name = <Table_Name>;
очень простое решение-добавить имя базы данных с именем таблицы, например, если ваше имя БД DBMS
и таблицы info
тогда это будет DBMS.info
для любого запроса.
если ваш запрос
select * from STUDENTREC where ROLL_NO=1;
он может показать ошибку, но
select * from DBMS.STUDENTREC where ROLL_NO=1;
это не так, потому что теперь на самом деле ваша таблица найдена.