create role语句必须由具备create role系统权限的用户(如sys、system或被显式授予该权限者)执行;普通用户如scott执行会报ora-01031错误,因connect角色仅含create session而不含create role。

CREATE ROLE 语句必须由具有 CREATE ROLE 权限的用户执行
普通用户无法创建角色,CREATE ROLE 是系统权限,只有 SYS、SYSTEM 或被显式授予 CREATE ROLE 的用户才能执行。用 scott 或开发账号直接运行会报 ORA-01031: insufficient privileges。
常见错误是误以为 GRANT CONNECT TO user 后就能建角色——其实 CONNECT 角色只含 CREATE SESSION,不带 CREATE ROLE。检查权限可用:SELECT * FROM SESSION_PRIVS WHERE PRIVILEGE = 'CREATE ROLE';
- 生产环境建议用
SYS AS SYSDBA执行,避免权限链断裂 - 若需授权给非 DBA 用户建角色,执行:
GRANT CREATE ROLE TO app_admin; - 角色名不能以数字开头,不能含空格或特殊字符(下划线除外)
批量授予权限要用 GRANT … TO role_name,不是 TO user
角色本身不“拥有”权限,而是作为权限容器;真正生效的是把权限 授予角色,再把角色授予用户。写成 GRANT SELECT ON hr.employees TO dev_role 是合法的,但写成 GRANT SELECT ON hr.employees TO dev_user 就绕过了角色机制。
批量授权最常用两种方式:
- 手动列出多个权限:
GRANT CREATE SESSION, CREATE TABLE, CREATE VIEW TO dev_role; - 批量生成对象权限语句(在
SYS下运行):SELECT 'GRANT SELECT ON '||owner||'.'||object_name||' TO dev_role;' FROM dba_objects WHERE owner = 'HR' AND object_type = 'TABLE';
注意:对象权限必须明确指定 schema(如 hr.employees),不能只写 employees,否则报 ORA-00942。
角色默认不激活,用户登录后需 SET ROLE 或设为 DEFAULT
即使把 dev_role 授予了用户,用户登录后执行 CREATE TABLE 仍可能报 ORA-01031——因为角色未默认启用。Oracle 默认只激活 DEFAULT 角色。
- 设为默认角色:
ALTER USER app_dev DEFAULT ROLE dev_role; - 临时启用(会话级):
SET ROLE dev_role IDENTIFIED BY password;(仅当角色带密码时需要) - 查看当前会话已启用角色:
SELECT * FROM SESSION_ROLES;
安全场景下常禁用默认角色,强制用 SET ROLE 显式切换,防止权限长期暴露。
用 PL/SQL 批量创建角色并授予权限要避开 EXECUTE IMMEDIATE 上下文陷阱
想一次性建 5 个角色并分别授不同权限?别直接写匿名块拼接字符串后 EXECUTE IMMEDIATE ——容易因权限作用域失败。例如在 PDB 中执行却未 ALTER SESSION SET CONTAINER = pdb_name,或在非 SYS 用户下尝试授 UNLIMITED TABLESPACE。
- 确保当前用户有所有目标权限的授予权(比如授
CREATE ANY TABLE需ADMIN OPTION) - 角色名、权限名必须全大写传入(除非建时加双引号),否则
EXECUTE IMMEDIATE会解析失败 - 更稳妥的做法:先用
SELECT生成完整 SQL 脚本,人工审核后再执行,而非全靠动态 SQL
真正容易被忽略的是角色依赖链:如果 dev_role 依赖 read_only_role,而后者尚未创建,GRANT dev_role TO user 不报错,但用户实际无法获得嵌套权限——Oracle 不自动展开角色继承关系,必须确保所有前置角色已存在且已授予权限。











