本篇探讨以下几个问题:
1. 在CDB级别中创建公共用户,不带 container 子句的效果;
2. 在CDB级别中创建公共用户,带 container=all 子句的效果;
3. 在CDB级别中创建公共用户,带 container=current 子句的效果;
4. 在PDB级别中创建本地用户,不带 container 子句的效果;
5. 在PDB级别中创建本地用户,带 container=all 子句的效果;
6. 在PDB级别中创建本地用户,带 container=current 子句的效果;
在理解上面问题之前,我们需要提前约定,就是需要提前知道:
1.CDB级别创建的用户称为公共用户,PDB级别创建的用户称为本地用户。
2. 公共用户命名规则对应参数common_user_prefix ,该参数值默认为C##。所以,在CDB级别创建公共用户,需要带 C##(也可以更改参数值)。
3. PDB$SEED 仅为种子容器,对应 CON_ID 为 2,只读模式,不参与讨论。
演示数据库版本:18.3.0.0.0(18c)
目录
1. CDB 不带 container 默认
2. CDB带 container=all
3. CDB带 container=current
4. PDB不带 container 默认
5. PDB带 container=all
6. PDB带 container=current
1. CDB 不带 container 默认
SQL>show con_id
CON_ID------------------------------
1SQL> create user c##cabc1 identified bycabc1;Usercreated.
SQL> select username,con_id from cdb_users where username='C##CABC1';
USERNAME CON_ID---------- ------
C##CABC1 1C##CABC13
所以,CDB级别创建公共用户,不带container子句,默认作用域范围:CDB和所有PDB
2. CDB带 container=all
SQL>show con_id
CON_ID------------------------------
1SQL> create user c##cabc2 identified by cabc2 container=all;Usercreated.
SQL> select username,con_id from cdb_users where username='C##CABC2';
USERNAME CON_ID---------- ------
C##CABC2 1C##CABC23
所以,CDB级别创建公共用户,带container=all子句,默认作用域范围:CDB和所有PDB。和不带效果一样。
3. CDB带 container=current
SQL>show con_id
CON_ID------------------------------
1SQL> create user c##cabc3 identified by cabc3 container=current;create user c##cabc3 identified by cabc3 container=current
*ERROR at line1:
ORA-65094: invalid local user or role name
所以,CDB级别创建公共用户,不能带 container=current 。因为是公共用户,默认作用于CDB及整个PDB。
4. PDB不带 container 默认
SQL> alter session set container=orders;
Session altered.
SQL> create user pdbabc1 identified bypdbabc1;Usercreated.
SQL> select username,con_id from cdb_users where username='PDBABC1';
USERNAME CON_ID---------- ------
PDBABC1 3
所以,PDB级别创建本地用户,不带container子句,默认作用域范围:当前PDB
5. PDB带 container=all
SQL> create user pdbabc2 identified by pdbabc2 container=all;create user pdbabc2 identified by pdbabc2 container=all
*ERROR at line1:
ORA-65050: Common DDLs only allowed in root.
所以,PDB级别创建本地用户,无法使用 container=all 子句。
6. PDB带 container=current
SQL> create user pdbabc3 identified by pdbabc3 container=current;Usercreated.
SQL> select username,con_id from cdb_users where username='PDBABC3';
USERNAME CON_ID---------- ------
PDBABC3 3
所以,PDB级别创建本地用户,带 container=current,作用域范围:当前PDB。
综上:
1. 在CDB级别中创建公共用户,不带 container 子句的效果: 作用于当前CDB和所有PDB
2. 在CDB级别中创建公共用户,带 container=all 子句的效果:作用于当前CDB和所有PDB
3. 在CDB级别中创建公共用户,带 container=current 子句的效果:X错误X CDB级别不能使用 CURRENT
4. 在PDB级别中创建本地用户,不带 container 子句的效果:作用于当前PDB
5. 在PDB级别中创建本地用户,带 container=all 子句的效果:X错误X PDB级别不能使用 ALL
6. 在PDB级别中创建本地用户,带 container=current 子句的效果:作用于当前PDB