set role后session_roles仍为空,说明角色未启用,常见原因包括os认证或jdbc连接未显式启用角色、角色带密码但未提供密码;必须执行set role role_name identified by password或set role all才能激活。
为什么set role后session_roles还是空
角色没出现在 session_roles 里,说明它根本没启用——哪怕你确认已用 grant 授予了该角色。常见原因是:用户以 identified externally(os 认证)方式登录,或 jdbc/cx_oracle 连接时未显式启用角色;也可能是角色带密码但 set role 没提供密码。
立即验证:SELECT * FROM SESSION_ROLES;
如果期望的角色(如 SELECT_CATALOG_ROLE)不在结果中,就不是“没授”,而是“没启”。
- 手动启用:执行
SET ROLE role_name IDENTIFIED BY password;(有密码时必须带)或SET ROLE ALL; - JDBC 连接后需额外执行一次
SET ROLE,驱动默认不启用任何角色 - OS 认证用户必须显式
SET ROLE,系统不会自动激活角色权限
PL/SQL里调用EXECUTE IMMEDIATE报ORA-01031
这是最隐蔽的坑:即使 SESSION_PRIVS 里有 CREATE TABLE,在存储过程里执行 EXECUTE IMMEDIATE 'CREATE TABLE ...' 仍会失败。因为 Oracle 规定——通过角色获得的系统权限,在 PL/SQL 运行时**默认不可见**。
- 必须直授:用
GRANT CREATE TABLE TO username;,不能只靠GRANT DBA TO username; - 检查是否误用了
AUTHID DEFINER:该模式下权限按定义者身份检查,但角色权限依然不生效 - 12c+ 可考虑
INHERIT PRIVILEGES,但需谨慎配置,且不解决角色权限问题
GRANT DBA后还是缺权限,是不是漏了ADMIN OPTION
DBA 角色本身不含 ADMIN OPTION,所以即使你被授予了 DBA,也无法用它去转授其他权限给他人。但这不是导致你自身操作报 ORA-01031 的原因——ADMIN OPTION 只影响“授出权”,不影响“使用权”。
真正卡住你的,往往是角色未启用,或跨 schema 操作时对象权限没直授。
- 查
SESSION_PRIVS:如果CREATE VIEW不在列表里,说明你缺的是这个系统权限,不是DBA角色本身 - 查
DBA_ROLE_PRIVS中ADMIN_OPTION列:为YES才能转授,但和当前报错无关 - 别依赖
GRANT DBA TO user一招鲜:它不自动启用,也不覆盖 PL/SQL 权限限制
Navicat连接后建视图失败,但SQL*Plus里可以
现象差异往往源于连接上下文不同:Navicat 默认用 JDBC 驱动,而 SQL*Plus 是原生客户端。JDBC 连接后,角色默认不启用,SESSION_ROLES 为空;SQL*Plus 则可能继承了 OS 或 profile 设置。
- 在 Navicat 执行任意语句前,先运行
SET ROLE ALL;或指定角色名 - 检查连接字符串是否含
currentSchema=xxx,这会改变默认 schema,间接影响对象解析和权限检查 - 避免在连接初始化脚本里漏掉
SET ROLE—— 很多 GUI 工具不自动执行它
角色是否启用、是否在 PL/SQL 中可见、是否被 JDBC 驱动忽略——这三个点各自独立,又常同时发生。最容易被忽略的是:你以为权限“授过了”,其实它一直躺在 DBA_ROLE_PRIVS 里,从未进入 SESSION_ROLES。











