上一次用 Oracle 还是 11g ,最近用的 19C 相比变化还不小,甚至连创建用户都超出我的已有知识范围。


问题

登入数据库,用 CREATE USER 创建用户,提示 ORA-65096: invalid common user or role name

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[oracle@Oracle19c ~]$ sqlplus

SQL*Plus: Release 19.0.0.0.0 - Production on Tue Nov 23 09:24:46 2021
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle.  All rights reserved.

ERROR:
ORA-12154: TNS:could not resolve the connect identifier specified


Enter user-name: system
Enter password:
Last Successful login time: Tue Nov 23 2021 09:11:07 +08:00

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0

SQL> CREATE USER "niceram" IDENTIFIED BY "passwd" DEFAULT TABLESPACE "USERS" TEMPORARY TABLESPACE "TEMP";
CREATE USER "niceram" IDENTIFIED BY "passwd" DEFAULT TABLESPACE "USERS" TEMPORARY TABLESPACE "TEMP"
            *
ERROR at line 1:
ORA-65096: invalid common user or role name

原因

Oracle 12c 后多了个 PDBCDB 的概念:

The multitenant architecture enables an Oracle database to function as a multitenant container database (CDB).

A CDB includes zero, one, or many customer-created pluggable databases (PDBs). A PDB is a portable collection of schemas, schema objects, and nonschema objects that appears to an Oracle Net client as a non-CDB. All Oracle databases before Oracle Database 12c were non-CDBs.

  • CDB (Container Database): 容器数据库。
    • 一个 CDB 中可以存在多个 PDB
    • 在 CDB 中只能创建公共普通用户,用户名以 C## 开头
    • 默认情况下,登录的数据库被指定为 CDB
  • PDB (Pluggable Databases): 可插拔数据库。
    • 在 PDB 可以创建本地用户,用户名无格式要求

综上,因为默认登录了 CDB,而创建用户时,用户名格式不符合要求,所以报错用户或角色名不可用。

对策

修正用户名

用户名前面加上 c##,在 CDB 下创建用户。

1
2
3
4
5
6
7
8
SQL> show con_name;

CON_NAME
------------------------------
CDB$ROOT
SQL> CREATE USER c##niceram IDENTIFIED BY passwd DEFAULT TABLESPACE USERS TEMPORARY TABLESPACE TEMP;

User created.

切换至 PDB

查看并切换到可用的 PDB 再创建用户。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
SQL> show con_name;

CON_NAME
------------------------------
CDB$ROOT
SQL> select pdb_name from cdb_pdbs; -- 查询所有 PDB 名称

PDB_NAME
--------------------------------------------------------------------------------
ORCLPDB1
PDB$SEED

SQL> alter session set container = ORCLPDB1;  -- 切换当前 session 到 ORCLPDB1

Session altered.

SQL> CREATE USER niceram IDENTIFIED BY passwd DEFAULT TABLESPACE USERS TEMPORARY TABLESPACE TEMP;

User created.

SQL>

可能存在的坑

创建用户的语句中,用户名加引号和不加引号是有区别的:

  • 有引号:用户名区分大小写,引号里是什么,创建后的用户名就是什么
  • 无引号:用户名不分大小写,创建后的用户名将自动转换为大写

乍一看好像是没什么特别大的影响,但是如果用户名用小写字母加引号创建,在某些第三方的可视化客户端将因不存在对应的用户而无法连接数据库。

相关文章

参考链接