Oracle如何创建只读用户
wptr33 2025-05-30 17:52 27 浏览
关注我「程序猿集锦」,获取更多分享。
- 背景
- 直接授予查询权限
- 通过角色来授予查询权限
- 同义词的使用
背景
现在有一个用户A,想把这个用户A下面的所有的表查询权限都赋予用户X,该怎么做?同样的问题,如果有4个用户A、B、C、D,需要把这4个用户下面所有的表的只读权限赋予用户X、Y、Z三个用户,我们该怎么做?
在MySQL5.7中,可以创建用户X,然后使用grant select on A.* to X这样的方式分别把每一个库下面所有的表都给用户X授权就可以实现。在MySQL8.0版本中,有了角色role的概念,我们只要把ABCD四个库下面所有表的只读权限都赋予一个只读角色,然后把这个只读的角色再赋予XYZ三个用户就可以了。
但是在Oracle中,没有基于类似于MySQL中的schema级别的授权,只能针对每一个用户下面每一个表分别授权。下面有2种方式可以实现Oracle只读用户授权。
直接授予查询权限
直接授权的方式就是把某一个用户下面的所有的数据库对象的对应权限,一一授权给指定的另外一个用户。下面我们演示一下具体的实现过程,把用户mydb下面的所有表的只读权限授权给my_ro_user用户。
以下操作都是使用system用户来执行的。
- 创建一个只读的用my_ro_user
create user my_ro_user identified by "my_ro_user";
- 给只读的用户授予连接权限
grant create session to my_ro_user;
- 把mydb下面的userinfo表的只读权限授权给my_ro_user用户
grant select on mydb.userinfo to my_ro_user;
上面只是把mydb下面的一个表授权给了my_ro_user用户,如果我们需要把mydb用户下面所有的表都授权给my_ro_user该如何做呢?在Oracle中没有grant select on mydb.* to my_ro_user这样功能,只能指定每一个数据库对象的名称。可以参考如下的方式,可以循环地把mydb下面的每一张表的查询权限都授权给my_ro_user用户。
BEGIN
-- FOR t IN (SELECT * FROM user_tables)
FOR t in (SELECT owner, object_name, object_type FROM all_objects WHERE owner = UPPER('mydb') AND object_type IN ('TABLE','VIEW','PROCEDURE','FUNCTION','PACKAGE'))
LOOP
-- EXECUTE IMMEDIATE 'GRANT SELECT ON ' || t.table_name || ' TO my_ro_user';
IF t.object_type IN ('TABLE','VIEW') THEN
EXECUTE IMMEDIATE 'GRANT SELECT ON '||t.owner||'.'||t.object_name||' TO my_ro_user';
-- ELSIF t.object_type IN ('PROCEDURE','FUNCTION','PACKAGE') THEN
-- EXECUTE IMMEDIATE 'GRANT DEBUG ON mydb.'||t.object_name||' TO my_ro_user';
END IF;
END LOOP;
END;
完成上面的授权操作之后,我们使用新的用户my_ro_user登录Oracle数据库之后,就可以查询到mydb用户下面的表中的数据了。
**注意:**此时在my_ro_user用户下面执行查询语句的时候,需要指定mydb这个用户名称,在所有的表前面都需要增加上mydb.这个字符串才可以查询到对应的表,不能直接执行select * from userinfo;,需要执行select * from mydb.userinfo;才可以。如果想写mydb.这个字符串就可以查询到对应的表,我们需要为my_ro_user赋予创建同义词的权限,然后再my_ro_user下面创建同义词才可以省略掉用户名称。
- 用system用户给my_ro_user用户授予创建同义词的权限。
grant create synonym to my_ro_user;
- 用my_ro_user登录Oracle然后执行如下语句,将SQL语句的结果复制出来执行即可批量创建出所有的同义词。
select
'create or replace synonym my_ro_user.' || object_name|| ' for ' || owner || '.' || object_name|| ';' ,
'drop synonym my_ro_user.' || object_name|| ';'
from dba_objects
where owner in upper('mydb')
and object_type='TABLE';
执行完上述SQL的结果集之后,my_ro_user在查询mydb用户下面的表时,就不用在指定mydb.字符串了。
通过角色来授予查询权限
创建一个角色,然后把对某个数据库下面的表的权限授予这个角色,然后再把这个角色赋予某一个用户。这样用户就可以以某种角色去访问某一个数据库下面的表了。
具体实现方式参考如下:
- 创建只读角色
create role my_readonly_role;
- 将数据库下面所有的表授权给角色
/*mydb是Oracle的数据库名称,也是用户名称,userinfo是mydb下面的表,my_readonly_role是一个角色名称*/
grant select on mydb.userinfo to my_readonly_role;
上面的方式比较麻烦,因为要对每一个表单独对角色进行授权。下面使用一个比较快的方式来解决这个授权的过程。
BEGIN
-- FOR t IN (SELECT * FROM user_tables)
FOR t in (SELECT owner, object_name, object_type FROM all_objects WHERE owner = UPPER('sunny_cmd') AND object_type IN ('TABLE','VIEW','PROCEDURE','FUNCTION','PACKAGE'))
LOOP
-- EXECUTE IMMEDIATE 'GRANT SELECT ON ' || t.table_name || ' TO my_readonly_role';
IF t.object_type IN ('TABLE','VIEW') THEN
EXECUTE IMMEDIATE 'GRANT SELECT ON '||t.owner||'.'||t.object_name||' TO my_readonly_role';
-- ELSIF t.object_type IN ('PROCEDURE','FUNCTION','PACKAGE') THEN
-- EXECUTE IMMEDIATE 'GRANT DEBUG ON mydb.'||t.object_name||' TO my_readonly_role';
END IF;
END LOOP;
END;
上面的SQL语句块中,使用到了查询某一个用户下面所有的数据库对象的查询方式,如果要查询某一个用户下面所有的数据库对象,可以通过如下的SQL语句:
/*查询mydb用户下面所有的数据库对象,包括表、视图、存储过程、函数、包。*/
SELECT * FROM all_objects WHERE owner = UPPER('mydb') AND object_type IN ('TABLE','VIEW','PROCEDURE','FUNCTION','PACKAGE')
- 创建只读用户
create user my_ro_user identified by "my_ro_user";
- 给新创建的用户授权登录的权限
grant create session to my_ro_user;
- 把只读角色授予新创建的只读用户
grant my_readonly_role to my_ro_user;
同义词的使用
当我们在只读用户下面,访问其他用户下面的只读权限的表时,如果不想在SQL语句中指定其他用户名称,那么就需要在当前只读的用户下面创建一个个表的同义词,让这个同义词自动指向其他用户下面对应的表,这样在只读用户下面就可以直接使用表名称,不用在每一个表名称前面增加用户名称了。
前提是当前只读的用户,对另外一个用户下的表,是有只读的权限的,然后在当前只读用户下创建同义词才可用,否则只要同义词没有对应的访问权限,通过同义词是不能访问到对应的数据表的。
- 上一篇:在MySQL命令行中获取用户账户列表的方法
- 下一篇:MySql安装与使用
相关推荐
- oracle数据导入导出_oracle数据导入导出工具
-
关于oracle的数据导入导出,这个功能的使用场景,一般是换服务环境,把原先的oracle数据导入到另外一台oracle数据库,或者导出备份使用。只不过oracle的导入导出命令不好记忆,稍稍有点复杂...
- 继续学习Python中的while true/break语句
-
上次讲到if语句的用法,大家在微信公众号问了小编很多问题,那么小编在这几种解决一下,1.else和elif是子模块,不能单独使用2.一个if语句中可以包括很多个elif语句,但结尾只能有一个...
- python continue和break的区别_python中break语句和continue语句的区别
-
python中循环语句经常会使用continue和break,那么这2者的区别是?continue是跳出本次循环,进行下一次循环;break是跳出整个循环;例如:...
- 简单学Python——关键字6——break和continue
-
Python退出循环,有break语句和continue语句两种实现方式。break语句和continue语句的区别:break语句作用是终止循环。continue语句作用是跳出本轮循环,继续下一次循...
- 2-1,0基础学Python之 break退出循环、 continue继续循环 多重循
-
用for循环或者while循环时,如果要在循环体内直接退出循环,可以使用break语句。比如计算1至100的整数和,我们用while来实现:sum=0x=1whileTrue...
- Python 中 break 和 continue 傻傻分不清
-
大家好啊,我是大田。...
- python中的流程控制语句:continue、break 和 return使用方法
-
Python中,continue、break和return是控制流程的关键语句,用于在循环或函数中提前退出或跳过某些操作。它们的用途和区别如下:1.continue(跳过当前循环的剩余部分,进...
- L017:continue和break - 教程文案
-
continue和break在Python中,continue和break是用于控制循环(如for和while)执行流程的关键字,它们的作用如下:1.continue:跳过当前迭代,...
- 作为前端开发者,你都经历过怎样的面试?
-
已经裸辞1个月了,最近开始投简历找工作,遇到各种各样的面试,今天分享一下。其实在职的时候也做过面试官,面试官时,感觉自己问的问题很难区分候选人的能力,最好的办法就是看看候选人的github上的代码仓库...
- 面试被问 const 是否不可变?这样回答才显功底
-
作为前端开发者,我在学习ES6特性时,总被const的"善变"搞得一头雾水——为什么用const声明的数组还能push元素?为什么基本类型赋值就会报错?直到翻遍MDN文档、对着内存图反...
- 2023金九银十必看前端面试题!2w字精品!
-
导文2023金九银十必看前端面试题!金九银十黄金期来了想要跳槽的小伙伴快来看啊CSS1.请解释CSS的盒模型是什么,并描述其组成部分。...
- 前端面试总结_前端面试题整理
-
记得当时大二的时候,看到实验室的学长学姐忙于各种春招,有些收获了大厂offer,有些还在苦苦面试,其实那时候的心里还蛮忐忑的,不知道自己大三的时候会是什么样的一个水平,所以从19年的寒假放完,大二下学...
- 由浅入深,66条JavaScript面试知识点(七)
-
作者:JakeZhang转发链接:https://juejin.im/post/5ef8377f6fb9a07e693a6061目录...
- 2024前端面试真题之—VUE篇_前端面试题vue2020及答案
-
添加图片注释,不超过140字(可选)...
- 今年最常见的前端面试题,你会做几道?
-
在面试或招聘前端开发人员时,期望、现实和需求之间总是存在着巨大差距。面试其实是一个交流想法的地方,挑战人们的思考方式,并客观地分析给定的问题。可以通过面试了解人们如何做出决策,了解一个人对技术和解决问...
- 一周热门
- 最近发表
-
- oracle数据导入导出_oracle数据导入导出工具
- 继续学习Python中的while true/break语句
- python continue和break的区别_python中break语句和continue语句的区别
- 简单学Python——关键字6——break和continue
- 2-1,0基础学Python之 break退出循环、 continue继续循环 多重循
- Python 中 break 和 continue 傻傻分不清
- python中的流程控制语句:continue、break 和 return使用方法
- L017:continue和break - 教程文案
- 作为前端开发者,你都经历过怎样的面试?
- 面试被问 const 是否不可变?这样回答才显功底
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)
