实际现象如下:

15:24:36 C@zkm(51)> select * FROM USER_TAB_PRIVS WHERE table_name='V_T';
GRANTEE                   OWNER                          TABLE_NAME                     GRANTOR                   PRIVILEGE                      GRANTABLE HIERARCHY
------------------------- ------------------------------ ------------------------------ ------------------------- ------------------------------ --------- ---------
C                         B                              V_T                            B                         SELECT                         NO        NO
Elapsed: 00:00:00.05
15:24:39 C@zkm(51)> select count(*) from b.v_t;
select count(*) from b.v_t
ERROR at line 1:
ORA-01031: insufficient privileges
Elapsed: 00:00:00.00

从视图user_tab_privs可以看出,C用户对表B.V_T(实际是视图)是有select权限的,但是查询确会报权限不足。

还真是奇葩。

实际上V_T是用户B的一个视图,V_T视图内容是查询用户A的表T。

看下实际环境构造时候的语句会更加直观明了。

1.sys管理员用户创建a,b,c三个用户并授权:
create user a identified by a;
create user b identified by b;
create user c identified by c;
grant resource,connect,unlimited tablespace,create synonym,create view to a,b,c;
2.登录用户a:
create table a.t (id int);
grant select on a.t to b;
3.登录用户b:
create view v_t as select * from a.t;
4.使用sys将b.v_t授权查询权限给用户c:
grant select on b.v_t to c;

按照上边的顺序执行后就将该现象重现出来了。

根本原因在于使用sys用户授权b.v_t给c用户的时候,虽然直接授权成功了,查询user_tab_privs也显示权限没有问题,但是实际上如果第4步使用b用户授权自己的视图v_t给c的时候会报错:

15:24:26 B@zkm(486)> grant select on b.v_t to c;
grant select on b.v_t to c
ERROR at line 1:
ORA-01720: grant option does not exist for 'A.T'

这样就明白了,b用户对a.t这个表只有查询权限,没法私自将a.t查询权限授权给c去查询。

解决方法就是让b用户也有讲a.t这个表给c用户的权限。

登录a用户:

grant select on t to b with grant option;

不需要在做其他操作,with grant option后c用户再次执行就不会报错了。

因为sys用户拥有最高权限,所以上边第4步骤直接执行成功了,但是我觉得Oracle应该有个校验然后报错提示才合理。