Oracle Database 12C帶來了新特性多租戶功能,在此之上,權限和角色也有新的變化,接下來将講解基于新特性下的賦予權限和角色。
1.公共角色
公共角色既可以存在于CDB root中,也可以存在于Application root中,同時應用于在root容器中的所有PDB。基于此特點,對于跨容器操作,公共角色是非常有用的,在操作之前要確定公共角色在每個PDB中都有角色。
公交角色的類型有2種:
1.Oracle自己提供的,例如DBA和PUBLIC。
2.使用者自己建立的,在CDB root或者Application root下,通過CREATE ROLE ... CONTAINER = ALL語句建立,角色字首必須是COMMON_USER_PREFIX,其預設值是c##或C##。

角色的作用範圍取決于定義這個角色的容器,如果在CDB root下定義,那麼其範圍就是整個CDB。如果在Application root下定義,那麼其範圍就是整個Application容器。
2.本地角色
通過CREATE ROLE ... CONTAINER = CURRENT(CONTAINER = CURRENT是預設值)建立的角色是本地角色,該角色隻存在于單一的PDB中,其作用範圍也隻限于所定義的PDB中。例如,在PDB1中建立了本地角色pdbrole,那麼pdbrole就被限制于PDB1中,在其他PDB中是不可用的。
屬于同一CDB或Application容器的PDB,可以建立相容名字的角色。例如,pdbrole建立于PDB1中,在PDB2中也可以建立相容名字的本地角色pdbrole。
3.賦予角色和權限
在CDB模式下,隻有2種方式去賦予權限和角色,公共方式和本地方式。
1.公共方式:GRANT ... TO USER CONTAINER=ALL
2.本地方式:GRANT ... TO USER CONTAINER=CURRENT
權限和角色如果以公共方式被賦予,那麼其作用範圍就在整個容器内,包括現有的PDB和未來新建立的PDB;如果以本地方式被賦予,那麼其作用範圍就在目前容器内。
使用者和角色可能是公共的或者本地的,但權限并不這樣區分。在CDB中,目前的容器是CDB root,那麼以公共方式賦權,那就意味着在整個CDB中都是有效的,包括容器下的所有PDB和未來建立的PDB,如果以本地方式賦權,那就意味着隻在目前容器有效。
下面來舉例來說明:
1) 建立公共角色c##user1,并以本地方式賦予create session權限
2) 建立公共角色c##role1,并本地方式賦予select any table權限
3) 本地方式将c##role1賦予c##user1
4) c##user1連接配接pdb1,連接配接失敗,缺少create session權限,這是因為本地方式賦予c##user1的create session隻在CDB root中有效
5) 連接配接pdb1,本地方式賦予c##user1權限connect和resource,再次用c##user1連接配接pdb1,連接配接成功
6) 查詢表現有表scott.emp,查詢失敗,報出表或視圖不存在錯誤
7) 在CDB root下,公共方式賦予c##role1權限select any table,再次c##user1連接配接pdb1,并查詢scott.emp,但還是報錯
8) 在CDB root下,公共方式賦予c##user1角色c##role1,再次c##user1連接配接pdb1,并查詢scott.emp,終于成功