可行,但需视图所有者对基表拥有 WITH GRANT OPTION 的 SELECT 权限;否则开发者查视图将报 ORA-01031,因 Oracle 不自动传递权限,且视图查询实际访问基表。
直接给开发者用户只授 select 权限到视图,不授任何基表权限 —— 这是可行的,但必须满足一个关键前提:视图所依赖的基表,其 select 权限必须由视图所有者以 with grant option 授出,否则开发者查视图会报 ora-01031: insufficient privileges。
为什么直接 grant select on view 不够用?
Oracle 视图本身不存数据,执行 SELECT 时实际是在访问底层基表。如果开发者用户没有基表的 SELECT 权限,哪怕视图存在、自己有视图 SELECT 权,查询仍会失败。
常见错误现象:
- 开发者执行
SELECT * FROM my_view;报错ORA-01031 - DBA 检查发现
GRANT SELECT ON my_view TO dev_user;已执行,但漏了基表授权
根本原因:Oracle 默认不传递权限。视图所有者(比如 app_owner)对 scott.emp 有 SELECT,不代表能自动让 dev_user 通过视图间接访问它。
必须用 WITH GRANT OPTION 授权基表
只有基表拥有者(或具有 ADMIN OPTION 的授权者)在授 SELECT 时加 WITH GRANT OPTION,视图所有者才能把该权限“转授”给视图的调用者。
实操步骤:
- 基表拥有者执行:
GRANT SELECT ON scott.emp TO app_owner WITH GRANT OPTION; - 视图所有者(
app_owner)创建视图:CREATE OR REPLACE VIEW emp_summary AS SELECT ename, deptno FROM scott.emp; - 视图所有者再授视图权限:
GRANT SELECT ON emp_summary TO dev_user;
注意:如果基表和视图同属一个用户(比如都是 app_owner 自己的表和视图),则无需 WITH GRANT OPTION —— 因为权限在同一 schema 内天然生效。
避免开发者绕过视图直查基表
即使你只给了视图权限,开发者仍可能通过以下方式尝试访问基表:
- 猜表名后执行
SELECT * FROM scott.emp;→ 报ORA-00942: table or view does not exist(只要没授基表权限,就看不到) - 查
ALL_TABLES或DBA_TABLES→ 需要额外权限,普通用户默认只能看到自己 schema 和已授权限的对象
真正要堵死路径,得配合最小权限原则:
- 不要给
SELECT ANY TABLE这类系统权限 - 不要把开发者加进
RESOURCE或DBA角色 - 确认
dev_user只有CONNECT+ 显式授予的视图SELECT
可验证:SELECT * FROM session_privs; 应只返回 CREATE SESSION 和 SELECT ANY DICTIONARY(如有)等极少数项;SELECT * FROM session_roles; 不应含高危角色。
跨数据库链路(DB Link)视图的特殊处理
如果视图里用了 @remote_db,权限模型更复杂:本地视图所有者需对 DB Link 有 EXECUTE 权限,且远程库对应用户也必须对目标表授 SELECT WITH GRANT OPTION —— 否则本地用户查视图仍会卡在远程端权限校验上。
典型报错:ORA-01017: invalid username/password; logon denied 或 ORA-02019: connection description for remote database not found,往往不是网络问题,而是远程库未正确授权。
容易被忽略的一点:DB Link 是 owner 级对象,dev_user 即使有视图权限,也无法直接用 SELECT * FROM t@remote_db; —— 除非显式授予了该 DB Link 的 SELECT 权限(Oracle 12c+ 支持),但绝大多数场景下应禁止这种直连。


















