Ошибка при попытке выдать права на представление пользователю: "ORA-01720: Grant Option Does Not Exist"

Есть представление:

select * 
from xxx 
where user_id = root.core.GetUserId() and account_id = root.core.GetAccountId();

но при попытке выдать права на представление пользователю client получаю ошибку:

ORA-01720: Grant Option Does Not Exist

У client нет прав на схему root и на пакет core, и давать не хотелось бы.

Можно ли как-то не давая дополнительных прав избавиться от ошибки?

По идее, ему и не нужны прямые права, так как root.core.GetUserId() находится в представлении.


Ответы (2 шт):

Автор решения: Sergey Zzz

Нужно выдать права grant EXECUTE ON ROOT.core to владелец_view WITH grant OPTION; И тогда если зайти под client view select * from xxx where user_id = root.core.GetUserId() and account_id = root.core.GetAccountId(); будет работать а запрос select root.core.GetUserId() from dual; - не будет.

→ Ссылка
Автор решения: 0xdb

Какая причина возникновения ошибки:

ORA-01720: Grant Option Does Not Exist

Посмотрим более детальное описание:

$ oerr ora 1720

01720, 00000, "grant option does not exist for '%s.%s'"
Cause: A grant was being performed on a view or a view was being replaced
and the grant option was not present for an underlying object.
Action: Obtain the grant option on all underlying objects of the view or
revoke existing grants on the view.

Создатель представления должен иметь право, давать права на все объекты в представлении, другим пользователям. Это достигается коммандой GRANT ... WITH GRANT OPTION:

WITH GRANT OPTION

Specify WITH GRANT OPTION to enable the grantee to grant the object privileges to other users and roles.

То есть, если B использует в представлении таблицу от A, то он должен получить от A разрешение давать пользоваться этой таблицей другим пользовтелям, даже если эти другие пользовтели уже имеют прямые права доступа к этой таблице. Короткий пример:

-- **А**
create table foo (val int)
/
grant select on foo to B with grant option; 

-- **B**
create view bar as select from a.foo
/
grant select on bar to someone;

Подробный и воспроизводимый пример есть в ответе на связанный вопрос.

→ Ссылка