Oracle不支持直接授权用户A所有表给用户B,需用dba_tables或all_tables生成GRANT语句,过滤BIN$%回收站对象,避免使用GRANT SELECT ANY TABLE,并可选创建同义词提升可用性。

不能直接用一条 GRANT 语句完成,必须通过动态 SQL 或脚本生成方式实现。Oracle 没有 “grant select on all tables of userA to userB” 这样的语法,硬写会报错。
用 dba_tables 生成授权语句(推荐,DBA 权限可用)
这是最常用、最可控的方式,适用于你有 DBA 或 SELECT_CATALOG_ROLE 权限的情况。
- 执行前确认当前用户能查
dba_tables:运行SELECT COUNT(*) FROM dba_tables WHERE owner = 'USERA';看是否返回非零值 - 生成授权语句(不执行,先预览):
SELECT 'GRANT SELECT ON ' || owner || '.' || table_name || ' TO USERB;' FROM dba_tables WHERE owner = 'USERA' AND table_name NOT LIKE 'BIN$%';
- 注意过滤回收站表(
BIN$%开头的),否则可能报ORA-00942: table or view does not exist - 把结果复制到 SQL*Plus / SQL Developer 中执行;或加
spool导出后批量运行
用 all_tables 生成语句(受限但更安全)
当你没有 DBA 权限,但已知 USERA 显式授予了你部分表的访问权,可以用 all_tables —— 它只列出你“当前能看到”的 USERA 的表。
- 适用场景:USERA 已手动给你授过几张表权限,你想基于已有可见范围批量补全
- 语句:
SELECT 'GRANT SELECT ON ' || owner || '.' || table_name || ' TO USERB;' FROM all_tables WHERE owner = 'USERA';
- 风险:如果 USERA 新增了表但没给你授权,这条语句就查不到,容易漏授
-
all_tables不包含回收站对象,无需额外过滤
避免踩坑:别用 GRANT SELECT ANY TABLE
这个系统权限看起来省事,但实际非常危险,且不符合最小权限原则。
- 它让 USERB 能查
SYS、SYSTEM下所有基表(如user$、obj$),等于暴露数据库元数据 - 一旦 USERB 被攻破或误操作,影响远超业务表范围
- 审计时会被标记为高风险配置,很多企业安全策略明令禁止
- 它不区分 owner,无法做到“只给 USERA 的表”,控制粒度太粗
授权后记得补同义词(可选但实用)
USERB 虽然有了查询权限,但每次写 SQL 还得带 USERA.TABLE_NAME,容易出错且不直观。
- 给 USERB 授权创建同义词:
GRANT CREATE SYNONYM TO USERB; - 再让 USERB 自己建同义词(或由 DBA 代建):
SELECT 'CREATE SYNONYM ' || table_name || ' FOR USERA.' || table_name || ';' FROM dba_tables WHERE owner = 'USERA';
- 注意:同义词名不能重复,若 USERB 已存在同名对象(如已有同名表/视图),建的时候会报
ORA-00955
真正麻烦的不是生成语句,而是确认 owner 名大小写、排除临时表/外部表/物化视图日志表等非标准对象——这些在 dba_tables 里都算“TABLE”,但业务上通常不需要授它们的 SELECT 权限。


















