在具有预先存在的 table 权限的用户之间共享 Oracle 视图

Sharing Oracle views between users with preexisting table permissions

当被授予者已经对基础 table 具有 select 权限但授予者对这些 "with grant" 没有权限时,是否可以授予使用视图的权限 tables?也就是说,被授予者是否可以使用视图的结构但使用他们自己的基础 table 权限而不是视图所有者的权限?

比如我有用户A、B、C,用户A有一些table。用户 B 和 C 当前对这些 table 具有相同的 select 权限。用户 B 在这些 table 上构建视图。用户 C 可以使用该视图吗?

注意:我知道如果 B 被授予对那些 table 的 "select with grant" 权限,那么这可以 运行 对 B 的权限,但我不希望 B能够向前授予他们的权限;我只希望已经拥有自己权限的用户能够使用视图的结构。

上下文:我想使用 A 模式中的一些数据做一些临时工作,这些数据是通过 B 模式中已经存在的视图查询的;这涉及创建一些 tables 来保存我想要使用的数据集,但我不想在工作时用这些 tables 弄乱 B 模式。我是否可以通过仅复制用户 B 对模式 A 的权限来以用户 C 的身份执行此操作,而不必在 C 模式中重新创建用户 B 的所有视图?有更简单的方法吗?

简短的回答是 "No"。 documentation is quite clear:

To grant SELECT on a view to another user, either you must own all of the objects underlying the view or you must have been granted the SELECT object privilege WITH GRANT OPTION on all of those underlying objects. This is true even if the grantee already has SELECT privileges on those underlying objects.

这是一个有效的例子。首先是助学金...

SQL> grant select on product to b;

Grant succeeded.

SQL> grant select on sales to b;

Grant succeeded.

SQL> grant select on product to c;

Grant succeeded.

SQL> grant select on sales to c;

Grant succeeded.

SQL> conn b/b
Connected.
SQL> select count(*) from a.sales;

  COUNT(*)
----------
        40

SQL> conn c/c
Connected.
SQL> select count(*) from a.sales;

  COUNT(*)
----------
        40

SQL> 

现在让我们在 B 的架构中创建一个视图。

SQL> conn b/b
Connected.
SQL> create or replace view tot_product_sales as
  2    select p.name as product_name
  3           , sum(s.pieces) as units_sold
  4           , sum(s.pieces * p.price) as turnover
  5    from a.sales s
  6         join a.product p on p.product_id = s.product_id
  7    group by p.name
  8  /

View created.

SQL> select * from tot_product_sales
  2  /

PRODUCT_NAME                   UNITS_SOLD   TURNOVER
------------------------------ ---------- ----------
Mobile                               1161     928800
Laptop                                970    1552485

SQL> grant select on tot_product_sales to c;
grant select on tot_product_sales to c
                *
ERROR at line 1:
ORA-01720: grant option does not exist for 'A.PRODUCT'


SQL> 

Oracle 安全模型为什么这样做?可以这样想:GRANT SELECT 允许用户 B 用 A 的数据做两件事

  • select 来自 A 表的数据
  • with grant option,允许其他用户 select 来自 A 的表的数据

B 无权知道 A 向哪些其他用户授予了特权。所以 B 无法知道 C 对 A 的模式有什么特权。

解决方案?

  1. A 授予 select ... with grant option 给 B(和 C)?
  2. B 和 C 创建重复视图
  3. A 创建视图并将其 select 授予 B 和 C

哪种解决方案最适合将取决于具体场景。通常是第三种选择,因为如果某些数据的特定表示有多个用例,则数据所有者拥有该表示是有意义的。其他时候,我们有一个专门的报告模式,可以整理、聚合和丰富来自多个模式的数据,在这种情况下,第一个选项就是那个。

您的情况似乎不符合这两种情况,因此复制模式 C 中的视图似乎是您的最佳选择。