ora-01031表示权限检查失败而非登录失败,主因是当前会话未启用角色、权限仅通过角色授予、pl/sql中角色权限不可用或os认证未激活权限;须查session_roles和session_privs确认实际生效权限,跨schema操作还需对象权限直授。
ora-01031 不是密码错,而是权限链断了
这个错误不会出现在登录环节(那是 ora-01017),而是在你执行 create view、create table、select from dba_users 等操作时突然抛出——说明 oracle 已认证你,但权限检查失败。关键点在于:它不告诉你缺哪个权限,只告诉你“当前上下文没通过”。常见诱因包括角色未启用、权限仅通过角色授予、pl/sql 中权限不可见、os 认证未激活系统权限等。
查 SESSION_ROLES 和 SESSION_PRIVS 才算真确认
别只看 DBA_ROLE_PRIVS 或 DBA_SYS_PRIVS,那只是“授过什么”,不是“现在能用什么”。必须在出错会话里立刻执行:
SELECT * FROM SESSION_ROLES;
如果期望的角色(如 SELECT_CATALOG_ROLE)不在列表中,说明它没启用;再执行:
SELECT * FROM SESSION_PRIVS;
这里列出的是当前会话**实际生效的系统权限**。如果 CREATE VIEW 报错,但 SESSION_PRIVS 里没有 CREATE VIEW,那就确认缺这个;如果只有 CREATE ANY VIEW,说明你被授予的是越权能力,而非基础权限。
- 若角色未启用:用
SET ROLE role_name IDENTIFIED BY password(如有密码)或SET ROLE ALL - 若用 JDBC/cx_Oracle 连接,默认不启用任何角色,需在连接后显式执行
SET ROLE - 若用 OS 认证(
IDENTIFIED EXTERNALLY),CREATE SESSION等关键权限可能不会自动激活,得手动SET ROLE
创建视图时缺的往往不止 CREATE VIEW
执行 CREATE OR REPLACE VIEW v_a AS SELECT * FROM other_schema.t 失败,光授 CREATE VIEW 没用。你还得确保:
- 当前用户有
SELECT权限 onother_schema.t——且必须是**直接授予**,不能仅靠角色(尤其在 PL/SQL 中) - 如果视图里查了数据字典(如
DBA_TABLES),还需SELECT ANY DICTIONARY或SELECT_CATALOG_ROLE(后者需启用) -
CREATE VIEW本身是系统权限,但若跨 schema 引用对象,对象权限和系统权限要分开补
典型错误写法:GRANT DBA TO user 后仍报错——因为 DBA 角色默认不启用,且其中的权限在存储过程中不可继承。
在存储过程中建表/建视图,权限必须直授
这是最隐蔽的坑:CREATE OR REPLACE PROCEDURE p AUTHID DEFINER AS BEGIN EXECUTE IMMEDIATE 'CREATE TABLE t1(id NUMBER)'; END; 即使用户有 CREATE TABLE 权限,只要它是通过角色获得的,就会报 ORA-01031。
- 正确做法:DBA 执行
GRANT CREATE TABLE TO user(不是GRANT DBA TO user) - 替代方案:改用
AUTHID CURRENT_USER,让过程以调用者身份运行,此时角色权限可用——但调用者自己也得有对应角色且已启用 - 注意:
CREATE ANY TABLE能绕过,但属于高危权限,生产环境应避免
真正容易被忽略的,是应用连上来时从不执行 SET ROLE,而你在 SQL*Plus 里测试一切正常——因为 SQL*Plus 默认启用默认角色,应用连接却不。











