根据需求的不同,也分为好几种方法,且看下文。

先构造基本的环境:创建两个用户AA,BB,基本需求为用户AA能够访问用户BB下所有的表,即用户AA有对BB下所有的表有“select on”权限。

SYS@zkm> create user aa identified by oracle account unlock;

User created.

SYS@zkm> create user bb identified by oracle account unlock;

User created.

SYS@zkm> grant connect,resource to aa,bb;

Grant succeeded.
SYS@zkm> create table bb.t1(id int); Table created. SYS@zkm> create table bb.t2(id int); Table created. SYS@zkm> conn aa/oracle
Connected.
AA@zkm> select * from bb.t1;
select * from bb.t1
*
ERROR at line 1:
ORA-00942: table or view does not exist

对用户BB创建了两张表T1和T2,用户AA并没有对这两张表访问权限。

根据需求,有方法1:

SYS@zkm> select 'grant select on "'||owner||'"."'||table_name||'" to aa;' grant_sql from dba_tables where owner='BB'; 

GRANT_SQL
--------------------------------------------------------------------------------
grant select on "BB"."T1" to aa;
grant select on "BB"."T2" to aa; SYS@zkm> grant select on "BB"."T1" to aa; Grant succeeded. SYS@zkm> grant select on "BB"."T2" to aa; Grant succeeded. SYS@zkm> conn aa/oracle
Connected.
AA@zkm> select * from bb.t1; no rows selected AA@zkm> select * from bb.t2; no rows selected

缺点也很明显,对于新增加的表用户AA仍然无权限访问。

方法2:

回收权限,重新进行新的实验。

AA@zkm> conn bb/oracle
Connected.
BB@zkm> revoke select on "BB"."T1" from aa; Revoke succeeded. BB@zkm> revoke select on "BB"."T2" from aa; Revoke succeeded. BB@zkm> conn aa/oracle
Connected.
AA@zkm> select * from bb.t1;
select * from bb.t1
*
ERROR at line 1:
ORA-00942: table or view does not exist

方法如下:

SYS@zkm> grant select any table to aa;

Grant succeeded.

SYS@zkm> conn aa/oracle
Connected.
AA@zkm> select * from bb.t1; no rows selected AA@zkm> select * from bb.t2; no rows selected

这种方法对新增加的表也有访问权限,缺点是除了SYS用户以外所有用户的表AA均有访问权限,由于权限被放大了,也就存在安全隐患。客户能接受是最方便的办法了。

方法3:

根据需求,不放大权限,并且对新建的表也有权限访问的话,目前我只想到用触发器来实现。先使用方法1对当前现有的表授权访问权限给AA,编写触发器实现BB创建新表后,触发授权动作达到目的。

回收select any table权限,并使用方法1对已有的表授权访问权限。

SYS@zkm> revoke select any table from aa;

Revoke succeeded.

SYS@zkm> grant select on "BB"."T1" to aa;

Grant succeeded.

SYS@zkm> grant select on "BB"."T2" to aa;

Grant succeeded.

不过在研究过程还是遇到一个问题,对于触发器触发的动作只能是DML操作,不能是DDL或者DCL。grant这个动作属于DCL操作会报错。详细见下文。

BB@zkm> create or replace trigger new_table_grant_tri
2 after create
3 on schema
4 declare
5 sqlstr varchar2(100);
6 begin
7 sqlstr:='grant select on '||ora_dict_obj_name||' to aa';
8 execute immediate sqlstr;
9 end;
10 / Trigger created. BB@zkm> create table t3(id int);
create table t3(id int)
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-30511: invalid DDL operation in system triggers
ORA-06512: at line 5 BB@zkm> !oerr ora 30511
30511, 00000, "invalid DDL operation in system triggers"
// *Cause: An attempt was made to perform an invalid DDL operation
// in a system trigger. Most DDL operations currently are not
// supported in system triggers. The only currently supported DDL
// operations are table operations and ALTER?COMPILE operations.
// *Action: Remove invalid DDL operations in system triggers.

上网找资料,发现一种技术叫“自治事务”,以前接触过一下没在意。

自治事务是在某个会话中独立开启一个事务,在其中处理的操作不会影响到同一会话中其他事务未提交的内容。反过来也是,同一会话的事务不会影响自治事务的内容。

于是将触发器改写如下:

BB@zkm> CREATE OR REPLACE TRIGGER new_table_grant_tri
2 after create
3 ON SCHEMA
4 DECLARE
5 PRAGMA AUTONOMOUS_TRANSACTION;
6 sqlstr varchar2(100);
7 BEGIN
8 IF ora_dict_obj_type='TABLE' THEN
9 sqlstr:='grant select on '||ora_dict_obj_name||' to aa';
10 execute immediate sqlstr;
11 COMMIT;
12 end if;
13 END;
14 / Trigger created. BB@zkm> create table t3(id int);
create table t3(id int)
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-04020: deadlock detected while trying to lock object BB.T3
ORA-06512: at line 7

目前尚不清楚ORA-4020错误产生原因。

换另外一种实现方式,先创建存储过程,该存储过程实现对新表授权动作。再创建触发器,调用该存储过程。如下:

BB@zkm> create or replace procedure new_table_grant_procedure(v_tabname IN VARCHAR2)
2 is
3 sqlstr VARCHAR2(200);
4 begin
5 sqlstr := 'grant select on ' || v_tabname ||' to aa';
6 execute immediate sqlstr;
7 end;
8 / Procedure created. BB@zkm> CREATE OR REPLACE TRIGGER new_table_grant_tri
2 after create
3 ON SCHEMA
4 DECLARE
5 PRAGMA AUTONOMOUS_TRANSACTION;
6 lv_job NUMBER;
7 BEGIN
8 IF ora_dict_obj_type='TABLE' THEN
9 DBMS_JOB.SUBMIT(lv_job,'new_table_grant_procedure('''||ora_dict_obj_name||''');');
10 COMMIT;
11 end if;
12 END;
13 / Trigger created. BB@zkm> create table t3(id int); Table created. BB@zkm> conn aa/oracle
Connected.
AA@zkm> select * from bb.t3; no rows selected

如果不使用DBMS_JOB.SUBMIT的方式同样会报错ORA-4020,待探究。

关于触发器的其他知识点:

ora_client_ip_address:用于返回客户端的IP地址
ora_database_name:用于返回当前数据库名
ora_des_encrypted_password:用于返回DES加密后的用户口令
ora_dict_obj_name:用于返回DDL操作所对应的数据库对象名
ora_dict_obj_name_list(name_list_ OUT ora_name_list_t):用于返回字事件中被修改的对象名列表
ora_dict_obj_owner:用于返回DDL操作所对应的对象的所有者名。
ora_dict_obj_ower_list(ower_list OUT ora_name_list_t):用于返回在事件中被修改对象的所有者列表
ora_dict_obj_type:用于返回DDL操作所对应的数据库对象的类型。
ora_grantee(user_list OUT ora_name_list_t):用于返回授权时事件授权者。
ora_instance_num:用于返回历程号。
ora_is_alter_column(column_name IN VARCHAR2):用于检测特定列是否被修改
ora_is_creating_nested_table:用于检测是否正在建立嵌套表
ora_is_drop_column(column_name IN VARCHAR2):用于检测特定列是否被删除
ora_is_servererror(error_number):用于检测是否返回了特定Oracle错误。
ora_login_user:用于返回登录用户名
ora_sysevent :用于返回触发 触发器的系统时间名。

内容大致以上这些。

【Oracle】如何让一个用户能够访问另外一个用户下所有的表的更多相关文章

  1. yabeblog.me 关于Tomcat7部署 一台机器部署两个项目,一个用域名访问,一个用IP访问

    该内容来自 http://www.yabeBlog.me,转载请说明出处. 1.使用IP访问的项目放在Tomcat7 的webapps目录下面:比如:AAA 2.使用域名访问的项目放在Tomcat7的 ...

  2. houxiurong.com 关于Tomcat7部署 一台机器部署两个项目,一个用域名访问,一个用IP访问

    该内容来自 http://houxiurong.com,转载请说明出处. 1.使用IP访问的项目放在Tomcat7 的webapps目录下面:比如:AAA 2.使用域名访问的项目放在Tomcat7的w ...

  3. 玩转SSRS第九篇---匿名访问的一个间接方法

    SSRS是一个功能丰富的报表平台,我们可以在这个平台上实现各种不同需求的报表应用,所以这个平台也吸引了很多.net框架之外的技术,希望能在应用中引入SSRS的报表,比如JSP或者PHP页面,这个时候系 ...

  4. MFC一个类访问另一个类成员对象的成员变量值

    MFC中一个类要访问另外一个类的的对象的成员变量值,这就需要获得原来那个类对象的指针,其实有好几种方法都可以实现. 比如维护一个单例模式.设置静态变量等等.我们这里举个列子,实现多个类之间的相互访问. ...

  5. XAMPP环境访问非Web DocumentRoot下绝对路径

    假设你的XAMPP网站文档根目录在C:/xampp/apache/htdocs/下面,那么访问这个目录下的文件是很直接的. 但是有时候需要把用户上传文件指定到特殊目录,比如E盘,那么就需要用户能够访问 ...

  6. 利用 awk 统计nginx 中某一个用户的访问次数

    线上总是会遇到攻击,所以就需要分析 access.log 看看那些用户的访问次数不正常,针对这些不正常的用户,要做处理,以 access.log为例说明下怎么统计. 通过 access.log 日志来 ...

  7. 创建一个欢迎 cookie 利用用户在提示框中输入的数据创建一个 JavaScript Cookie,当该用户再次访问该页面时,根据 cookie 中的信息发出欢迎信息。

    创建一个欢迎 cookie 利用用户在提示框中输入的数据创建一个 JavaScript Cookie,当该用户再次访问该页面时,根据 cookie 中的信息发出欢迎信息. <html> & ...

  8. Oracle总结【视图、索引、事务、用户权限、批量操作】

    前言 在Oracle总结的第一篇中,我们已经总结了一些常用的SQL相关的知识点了...那么本篇主要总结关于Oralce视图.序列.事务的一些内容... 在数据库中,我们可以把各种的SQL语句分为四大类 ...

  9. oracle ebs应用产品安全性-定义访问权限集

    定义 定义访问权限集是一项分配至责任层的可选的安全功能,是对Oracle 11i应用产品弹性域安全性定义的功能扩展,对总帐管理模块的一些内容进行安全性定义和权限分配的集合,以控制不同的责任对一些内容的 ...

随机推荐

  1. Java实现字符串转换成整数

    1 问题描述 输入一个由数字组成的字符串,请把它转换成整数并输出.例如,输入字符串"123",输出整数123. 请写出一个函数实现该功能,不能使用库函数. 2 解决方案 解答本问题 ...

  2. PAT 到底买不买

    小红想买些珠子做一串自己喜欢的珠串.卖珠子的摊主有很多串五颜六色的珠串,但是不肯把任何一串拆散了卖.于是小红要你帮忙判断一下,某串珠子里是否包含了全部自己想要的珠子?如果是,那么告诉她有多少多余的珠子 ...

  3. 彻底解决go get golang.org/x等包失败与VSCode golang插件安装失败问题

    由于某种众所周知的一些原因,https://golang.org/ golang 的官方域名是被墙了的,这也就导致了, 在广大 go 开发者使用 golang 的时候,总会出现 go get 失败的问 ...

  4. jenkins 添加用户管理权限

    一.前言 小组开会通知 想把jenkins 构建的权限给开发,这样的话效率会增加.运维也不必每次帮助开发去构建发布. 1.规划 jenkins 四个项目分别对应三个人负责.项目下的只负责 CI.UAT ...

  5. 下拉式菜单中的内容堆叠(ul型)

    今天使用ul创建下拉式菜单,菜单中的内容堆在了一起. 这是我的html代码 <!DOCTYPE html> <html lang="en"> <hea ...

  6. vue2.0+Element UI 表格前端分页和后端分页

    之前写过一篇博客,当时对element ui框架还不太了解,分页组件用 html + css 自己写的,比较麻烦,而且只提到了后端分页 (见 https://www.cnblogs.com/zdd20 ...

  7. nacos基础--客户端下载

    对于nacos的作用,我在这里不在过多介绍,不知道的同学可以自行先了解,对于nacos,有官网进行介绍,对于一个初学者来说是一件非常方便的事情. 官网地址:https://nacos.io 但是在下载 ...

  8. Cookie和localStorage的查询、设置、修改及删除

    感谢:链接(视频讲解很详细) cookie:是一种字符串表示的数据,用于在本地记录用户的基本信息(账号,密码等),具有时限性. 数据的具体内容: (图源上文视频链接) localStorage:与co ...

  9. Docker巨轮的航行之路-基础知识篇

    一.什么是Docker Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中 ...

  10. rust 宏

    macro_rules! four { () => {1 + 3}; } fn main(){ println!("{}", 1+four!()); println!(&qu ...