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

先构造基本的环境:创建两个用户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实现 LeetCode 233 数字 1 的个数

    233. 数字 1 的个数 给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数. 示例: 输入: 13 输出: 6 解释: 数字 1 出现在以下数字中: 1, 10, 11, 1 ...

  2. Java实现 蓝桥杯 乘积最大

    输入输出样例 输入样例#1: 4 2 1231 输出样例#1: 62 import java.util.Scanner; public class chengjizuida { public stat ...

  3. java实现自行车行程

    ** 自行车行程** 计算行程 低碳生活,有氧运动.骑自行车出行是个好主意.小明为自己的自行车装了个计数器,可以计算出轮子转动的圈数.在一次骑车旅行中,出发时计算器的示数为begin,到达目的地时的示 ...

  4. java实现第六届蓝桥杯三羊献瑞

    三羊献瑞 题目描述 观察下面的加法算式: 祥 瑞 生 辉 三 羊 献 瑞 三 羊 生 瑞 气 (如果有对齐问题,可以参看[图1.jpg]) 其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字. ...

  5. 【asp.net core 系列】4. 更高更强的路由

    0. 前言 在之前我们介绍了请求通过路由寻找到控制器,以及控制器与视图的数据流转.那么,我们回过头来,再看看路由的一些其他用法. 1. 路由属性(Route Attribute) 按照英文的直接翻译, ...

  6. 三分钟搭建websocket实时在线聊天,项目经理也不敢这么写

    我们先看一下下面这张图: 可以看到这是一个简易的聊天室,两个窗口的消息是实时发送与接收的,这个主要就是用我们今天要讲的websocket实现的. websocket是什么? websocket是一种网 ...

  7. 【快手初面】要求3个线程按顺序循环执行,如循环打印A,B,C

    [背景]这个题目是当时远程面试时,手写的题目.自己比较惭愧,当时写的并不好,面试完就又好好的完善了下. 一.题意分析 3个线程要按顺序执行,就要通过线程通信去控制这3个线程的执行顺序. 而线程通信的方 ...

  8. 免费 IP 代理池示例

    使用文档 import requests import re import random from concurrent.futures import ThreadPoolExecutor impor ...

  9. (一)JavaMail发送简单邮件

    1,导入依赖 <dependency> <groupId>com.sun.mail</groupId> <artifactId>jakarta.mail ...

  10. Jenkins项目构建运行

    [准备环境] 继Jenkins环境搭建完成后,进行插件的管理 [思路] 项目顺序是,开发提交代码到代码仓库,测试通过Jenkins拉下开发的代码打包部署: 1.开发提交代码 2.Jenkins自动从代 ...