Как правильно дать права на доступ к представлению? Ошибка ORA-00942

Ламерский вопрос.
Есть схемы owner1 и owner2.

Под пользователем owner1 создаю view на основе таблиц owner1.t1, owner1.t2, owner1.t3.

Даю пользователю owner2 права на select из таблиц owner1.t1, owner1.t2, owner1.t3.

Запрос под пользователем owner2 из указанных таблиц в схеме owner1 проходит. А вот на запрос под owner2 из представления owner1.view получаю ошибку:

ORA-00942: Table or view does not exist

В чем может быть проблема?


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

Автор решения: 0xdb

Вопрос далеко не ламерский. Проблема в неполном понимании, зачем нужны представления. Коротко процитирую из документации:

Views enable you to tailor the presentation of data to different types of users. Views are often used to:

  • Provide an additional level of table security by restricting access to a predetermined set of rows or columns of a table

  • Hide data complexity

For example, a single view can be defined with a join, which is a collection of related columns or rows in multiple tables. However, the view hides the fact that this information actually originates from several tables. A query might also perform extensive calculations with table information. Thus, users can query a view without knowing how to perform a join or calculations.

Владелец таблиц с данными (owner1) даёт посредством представлений другим пользователям (приложениям) доступ к данных из своих таблиц в том виде и объёме, в котором он считает нужным, но при этом скрывая, как выглядят данные на самом деле и откуда они происходят.

Представление в запросе выполняется с правами его владельца (owner1), а не с правами того, кто выполняет запрос (owner2). То есть, владелец представления должен дать права на представление, но ни в коем случае не на таблицы, которые входят в представление.

Как это выглядит на примере. Как owner1 выполните:

create table t1 (id, name, memo) as
    select 1, 't1', 't1 info invisible by others' from dual
/
create table t2 (id, name, memo) as
    select 1, 't2', 't2 info invisible by others' from dual
/
create or replace view v1 (name1, name2, memo) as
    select t1.name, t2.name, 't1,t2 info visible by others'
    from t1 join t2 on t2.id=t2.id;

grant select on v1 to owner2;

Теперь owner2 видит только то, что ему положено:

connect owner2/pass@dbsrv/db1

select * from owner1.v1
/
NA NA MEMO
-- -- ----------------------------
t1 t2 t1,t2 info visible by others

Но не видит самих таблиц, которые принадлежат owner1:

 select * from owner1.t1
  2  /
select * from owner1.t1
                     *
ERROR at line 1:
ORA-00942: table or view does not exist
→ Ссылка