在Oracle数据库中,不同用户默认是相互隔离的,每个用户只能访问自己模式下的数据库对象,如果需要访问其他用户创建的对象,必须通过权限授予的方式实现。Oracle的权限体系分为系统权限和对象权限,不同用户之间的跨模式访问主要依赖对象权限的授予。

Oracle用户权限基础
Oracle的权限分为两类,系统权限允许用户执行特定的数据库操作,比如创建表、创建会话等;对象权限允许用户对特定的数据库对象执行操作,比如查询表、修改视图等。不同用户之间的跨模式访问,核心就是对象权限的授予。
常见的对象权限包括:
- SELECT:允许查询表或视图的数据
- INSERT:允许向表中插入数据
- UPDATE:允许修改表中的数据
- DELETE:允许删除表中的数据
- EXECUTE:允许调用存储过程、函数或包
- ALTER:允许修改表的结构
不同用户之间的对象授权操作
授予对象权限
假设用户user_a下有一张名为emp_info的表,现在需要让用户user_b可以查询这张表的数据,由user_a执行以下授权语句:
-- user_a 用户执行,授予user_b查询emp_info表的权限 GRANT SELECT ON emp_info TO user_b;
如果需要授予多个权限,可以在一条语句中指定:
-- 授予user_b对emp_info表的查询、插入、修改权限 GRANT SELECT, INSERT, UPDATE ON emp_info TO user_b;
如果需要让user_b可以把这个权限再传递给其他用户,可以在授权时加上WITH GRANT OPTION:
-- 授予user_b查询权限,并且允许user_b把这个权限授予其他用户 GRANT SELECT ON emp_info TO user_b WITH GRANT OPTION;
回收对象权限
当不再需要让其他用户访问自己的对象时,可以回收已授予的权限,回收权限使用REVOKE语句:
-- user_a 用户执行,回收user_b对emp_info表的查询权限 REVOKE SELECT ON emp_info FROM user_b;
授权后访问其他用户对象的方式
其他用户获得授权后,访问对象时需要在对象名前加上对象所属用户的模式名作为前缀,格式为模式名.对象名。
比如user_b要查询user_a的emp_info表,需要执行:
-- user_b 用户执行查询 SELECT * FROM user_a.emp_info;
如果觉得每次写模式名前缀比较麻烦,可以创建同义词来简化访问。同义词相当于对象的别名,创建后可以直接使用同义词访问对象。
创建同义词的语法如下:
-- user_b 用户执行,创建emp_info表的同义词,之后可以直接用emp_info访问 CREATE SYNONYM emp_info FOR user_a.emp_info;
创建同义词后,user_b就可以直接执行查询:
SELECT * FROM emp_info;
常见注意事项
- 只有对象的拥有者或者拥有该对象
GRANT ANY OBJECT PRIVILEGE系统权限的用户,才能授予其他用户该对象的权限 - 回收权限时,如果被授予者之前通过
WITH GRANT OPTION把权限传递给了其他用户,回收权限时这些传递的权限也会被一并回收 - 如果对象所属用户删除了该对象,那么其他用户获得的该对象的权限也会自动失效
- 系统权限的授予和回收使用
GRANT 系统权限 TO 用户和REVOKE 系统权限 FROM 用户的语法,和对象权限的语法不同,不要混淆
权限查询方法
如果需要查看当前用户拥有哪些其他用户授予的对象权限,可以查询USER_TAB_PRIVS_RECD数据字典:
-- 查询当前用户被授予的对象权限 SELECT grantee, table_schema, table_name, privilege FROM user_tab_privs_recd;
如果需要查看当前用户把自己的哪些对象权限授予了其他用户,可以查询USER_TAB_PRIVS_MADE数据字典:
-- 查询当前用户授予其他用户的对象权限 SELECT grantee, table_name, privilege FROM user_tab_privs_made;