既然以上提到的这三类字典都是视图(VIEW),那这些视图是怎样建立起来的?又是如何实现的权限控制呢?我们一起来探索一下Oracle的实现。
通常USER_类视图不包含Owner字段,查询潜在的返回当前用户的对象信息,我们以USER_TABLES视图为例(篇幅原因,省略了部分内容)看一下其创建及结构:
create or replace view USER_TABLES (TABLE_NAME, TABLESPACE_NAME, CLUSTER_NAME, IOT_NAME, PCT_FREE, PCT_USED, ……. DEGREE, INSTANCES, CACHE, TABLE_LOCK, SAMPLE_SIZE, LAST_ANALYZED, PARTITIONED, IOT_TYPE, TEMPORARY, SECONDARY, NESTED, BUFFER_POOL, ROW_MOVEMENT, GLOBAL_STATS, USER_STATS, DURATION, SKIP_CORRUPT, MONITORING, CLUSTER_OWNER, DEPENDENCIES, COMPRESSION) as select o.name, decode(bitand(t.property, 4194400), 0, ts.name, null), decode(bitand(t.property, 1024), 0, null, co.name), …… from sys.ts$ ts, sys.seg$ s, sys.obj$ co, sys.tab$ t, sys.obj$ o, sys.obj$ cx, sys.user$ cu where o.owner# = userenv('SCHEMAID') and o.obj# = t.obj# ….. and t.dataobj# = cx.obj# (+) and cx.owner# = cu.user# (+) /
我们注意到Where条件中有这样一个限制:
where o.owner# = userenv('SCHEMAID')
这就限制了当前查询只返回当前用户的SCHEMA对象信息。
而对于ALL_TABLES视图,在Where子句中,关于用户部分,增加了这样一个条件:
and (o.owner# = userenv('SCHEMAID') or o.obj# in (select oa.obj# from sys.objauth$ oa where grantee# in ( select kzsrorol from x$kzsro ) ) or /* user has system privileges */ exists (select null from v$enabledprivs where priv_number in (-45 /* LOCK ANY TABLE */, -47 /* SELECT ANY TABLE */, -48 /* INSERT ANY TABLE */, -49 /* UPDATE ANY TABLE */, -50 /* DELETE ANY TABLE */) ) )
这个条件扩展了关于用户有权限访问的对象信息,所以实际上USER_TABLES的结果是ALL_TABLES结果的一个子集。
DBA_TABLES视图的Where条件中,则没有关于Owner的限制,所以查询返回了数据库中所有表的信息:
where o.owner# = u.user# and o.obj# = t.obj# and bitand(t.property, 1) = 0 and t.bobj# = co.obj# (+) and t.ts# = ts.ts# and t.file# = s.file# (+) and t.block# = s.block# (+) and t.ts# = s.ts# (+) and t.dataobj# = cx.obj# (+) and cx.owner# = cu.user# (+) /
这就是这几类数据字典视图的区别所在,也就是Oracle实现权限隔离的方式。
最后修改时间:2019-07-24 10:42:23
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。