应用容器

在 CDB 中,可以为可由 PDB 共享的应用程序数据和元数据创建容器。

关于应用程序容器

应用程序容器是用户创建的可选 CDB 组件,用于存储一个或多个应用程序后端的数据和元数据。CDB 包含零个或多个应用程序容器。

在 application container(应用程序容器)中, application(应用程序)是存储在应用程序根中的公用数据和元数据的命名版本化集。在应用程序容器的上下文中,“应用程序”一词是指“主应用程序定义”。例如,应用程序可能包括表、视图和程序包的定义。

例如,可以在一个应用程序容器内创建多个与销售相关的 PDB,这些 PDB 共享一个包含一组公用表和表定义的应用程序。可以将多个与 HR 相关的 PDB 存储在一个单独的应用程序容器中,并具有自己的公用表和表定义。

带有 AS APPLICATION CONTAINER 子句的 CREATE PLUGGABLE DATABASE 语句将创建应用程序容器的应用程序根,从而隐式创建应用程序容器本身。首次创建应用程序容器时,它不包含任何 PDB。要创建应用程序 PDB,必须连接到应用程序根,然后执行 CREATE PLUGGABLE DATABASE 语句。

在 CREATE PLUGGABLE DATABASE 语句中,必须指定容器名称(与应用程序根名称相同),例如 saas_sales_ac。应用程序容器名称在 CDB 内以及通过特定监听程序访问其实例的所有 CDB 的范围内必须唯一。每个应用程序容器都有一个与应用程序容器同名的默认服务。

应用程序容器的用途

在某些方面,应用程序容器在 CDB 内充当特定于应用程序的 CDB。应用程序容器(如 CDB 本身)可以包含多个 PDB,并允许这些 PDB 共享元数据和数据。

应用程序根使应用程序 PDB 能够共享应用程序,在这种情况下,这意味着一组命名且版本化的公用元数据和数据。典型的应用程序将安装应用程序公用用户、元数据链接公用对象和数据链接公用对象。

应用容器的关键优势

与将每个应用程序存储在单独的 PDB 中相比,应用程序容器具有多项优势。

应用容器用例:SaaS

SaaS 部署可以使用多个应用程序 PDB,每个应用程序 PDB 分别用于共享元数据和数据的单独客户。

在纯 SaaS 环境中,主应用程序定义位于应用程序根中,但特定于客户的数据驻留在自己的应用程序 PDB 中。例如,sales_app 是应用程序根中的应用程序模型。名为 cust1_pdb 的应用程序 PDB 仅包含客户 1 的销售数据,而名为 cust2_pdb 的应用程序 PDB 仅包含客户 2 的销售数据。插入、断开、克隆和其他 PDB 级别操作可用于各个客户 PDB。

图 1:SaaS 用例

插图 cncpt389.png 的说明

纯 SaaS 配置具有以下优点:

应用容器用例:逻辑数据仓库

客户可以使用多个应用程序 PDB 来解决数据主权问题。

在示例用例中,公司将特定于每个财务季度的数据放在一个单独的 PDB 中。例如,名为 sales_ac 的应用程序容器包括 q1_2016_pdb、q2_2016_pdb、q3_2016_pdb 和 q4_2016_pdb。在 PDB 中定义与关联季度对应的每个事务处理。要生成一个聚合一年性能的报告,可使用 CONTAINERS() 子句跨四个 PDB 进行聚合。

这种逻辑仓库设计的好处包括:

应用程序根

应用程序容器只有一个 application root ,即容器中应用程序 PDB 的父项。

作为应用程序根的属性是在创建时建立的,无法更改。应用程序根所属的唯一容器是 CDB 根。应用程序根在某些方面类似于 CDB 根,而在其他方面类似于 PDB:

应用程序根不同于 CDB 根和标准 PDB,因为它可以存储用户创建的公用对象,这些公用对象称为应用程序公用对象。应用程序公用对象可由插入到应用程序根的应用程序 PDB 访问。应用程序公用对象对于 CDB 根、其他应用程序根或不属于该应用程序根的 PDB 不可见。

示例 3-1 创建应用程序根

在此示例中,您以管理公用用户 c##system 的身份登录到 CDB 根。您可以创建一个名为 saas_sales_ac 的应用程序容器,然后打开与容器同名的应用程序根。

-- Create the application container called saas_sales_ac
CREATE PLUGGABLE DATABASE saas_sales_ac AS APPLICATION CONTAINER
  ADMIN USER saas_sales_ac_adm IDENTIFIED BY manager;

-- Open the application root
ALTER PLUGGABLE DATABASE saas_sales_ac OPEN;

将当前容器设置为 saas_sales_ac,然后验证此容器是否为应用程序根:

-- Set the current container to saas_sales_ac
ALTER SESSION SET CONTAINER = saas_sales_ac;

COL NAME FORMAT a15
COL ROOT FORMAT a4
SELECT CON_ID, NAME, APPLICATION_ROOT AS ROOT,
       APPLICATION_PDB AS PDB,
FROM   V$CONTAINERS;

    CON_ID NAME            ROOT PDB
---------- --------------- ---- ---
         3 SAAS_SALES_AC   YES	NO

对于应用程序容器,您可以在 SYS_CONTEXT 函数的 USERENV 名称空间中指定以下两个参数。

SYS_CONTEXT('USERENV', 'IS_APPLICATION_ROOT')
SYS_CONTEXT('USERENV', 'IS_APPLICATION_PDB')

应用程序根中 SYS_CONTEXT('USERENV', 'IS_APPLICATION_ROOT') 的值如下所示:

SQL> select sys_context('USERENV', 'IS_APPLICATION_ROOT') from dual;

SYS_CONTEXT('USERENV','IS_APPLICATION_ROOT')
--------------------------------------------------------------------------------
YES

请注意,SYS_CONTEXT('USERENV', 'IS_APPLICATION_ROOT') 的值与 V$PDBS 视图中的列 APPLICATION_ROOT 匹配。

SQL> select application_root from v$pdbs where con_id=sys_context('USERENV', 'CON_ID');

APP
---
YES

应用程序 PDB

应用程序 PDB 是位于应用程序容器中的 PDB。CDB 中的每个 PDB 都位于零个或一个应用程序容器中。

例如,saas_sales_ac 应用程序容器可能支持多个客户,每个客户应用程序将其数据存储在单独的 PDB 中。应用程序 PDB cust1_sales_pdb 和 cust2_sales_pdb 可能位于 saas_sales_ac 中,在这种情况下,它们不属于其他应用程序容器(尽管它们必然也属于 CDB 根的 PDB)。

连接到应用程序根时,通过执行 CREATE PLUGGABLE DATABASE 创建应用程序 PDB。可以从种子创建应用程序 PDB,也可以克隆 PDB 或插入断开的 PDB。与插入到 CDB 根的 PDB 类似,您可以克隆、断开或删除应用程序 PDB。但是,应用程序 PDB 必须始终属于应用程序根。

应用产品种子

应用程序种子是在应用程序容器内由用户创建的可选 PDB。应用程序容器具有零个或一个应用程序种子。

通过应用程序种子,可以快速创建应用程序 PDB。它在应用程序容器中发挥的作用与 PDB$SEED 在 CDB 本身中发挥的作用相同。

应用程序种子名称始终为 application_container_name$SEED,其中 application_container_name 是应用程序容器的名称。例如,使用 CREATE PDB ... AS SEED 语句在 saas_sales_ac 应用程序容器中创建 saas_sales_ac$SEED。

应用程序公用对象

应用程序公用对象是在应用程序根中的应用程序内创建的公用对象。公用对象是数据链接对象或元数据链接对象。

对于数据链接公用对象,应用程序 PDB 共享一组数据。例如,saas_sales_ac 应用程序容器的应用程序名为 saas_sales_app,具有版本 1.0,并包含数据链接 usa_zipcodes 表。在这种情况下,行在应用程序根的表中存储一次,但在所有应用程序 PDB 中都可见。

对于元数据链接公用对象,应用程序 PDB 仅共享元数据,但包含不同的数据集。例如,元数据链接 products 表在每个应用程序 PDB 中具有相同的定义,但行本身特定于 PDB。名为 cust1pdb 的应用程序 PDB 可能具有包含工作簿的 products 表,而名为 cust2pdb 的应用程序 PDB 可能具有包含自动部件的 products 表。

关于 CDB 中的公用性

CDB 或应用程序根中定义的常见现象在插入到此根的所有容器中都是相同的。

共同性原则

在 CDB 中,一种现象在系统容器(CDB 本身)或特定应用程序容器中可能是常见的。

例如,如果在连接到 CDB$ROOT 时创建公用用户帐户,则此用户帐户对 CDB 中的所有 PDB 和应用程序根是公用的。但是,如果在连接到应用程序根时创建应用程序公用用户帐户,则此用户帐户仅对该应用程序容器中的 PDB 公用。

在 CDB$ROOT 或应用程序根的上下文中,通用性原则如下:

CDB 中的名称空间

在 CDB 中,每个对象的名称空间都限定在其容器中。

以下原则概括了范围规则:

上述原则对地方和共同现象有影响。

当地现象

本地现象必须唯一地命名为在容器内,但不能在 CDB 的所有容器中命名。不同容器中同名的局部现象是不同的。例如,一个 PDB 中的本地用户 sh 与另一个 PDB 中的本地用户 sh 不冲突。

CDB$ROOT 常见现象

CDB$ROOT 中定义的常见现象存在于多个容器中,并且必须在每个名称空间中唯一。例如,CDB 根包括预定义的公用用户,例如 SYSTEM 和 SYS。为了确保名称空间分离,Oracle AI Database 阻止在另一个容器中创建 SYSTEM 用户。

要确保名称空间分隔,CDB 根中由用户创建的公用现象的名称必须以 COMMON_USER_PREFIX 初始化参数指定的值开头。缺省前缀为 c## 或 C##。所有其他用户创建的现象的名称不得以 c## 或 C## 开头。例如,无法在名为 c##hr 的 hrpdb 中创建本地用户,也无法在名为 hr 的 CDB 根中创建公用用户。

应用程序常见现象

在应用程序容器中,本地和应用程序常见现象的名称不得冲突。

另请参阅:Oracle AI Database Security Guide 以了解有关公用用户和角色的更多信息

创建应用程序公用对象

要创建公用对象,请连接到应用程序根,然后执行指定共享属性的 CREATE 语句。

您只能在应用程序安装、升级或修补过程中创建或更改应用程序公用对象。您可以通过以下方式指定共享:

下表显示了应用程序公用对象的类型以及数据和元数据的存储位置。

表 1 应用程序公用对象

对象类型 共享值 元数据存储 数据存储
数据链接 DATA 应用程序的根 应用程序的根
扩展数据链接 EXTENDED DATA 应用程序的根 应用产品根和应用 PDB
元数据链接 METADATA 应用程序的根 应用程序 PDB

另请参阅:Oracle AI Database Security Guide 以了解如何管理公用对象的权限

元数据链接的应用程序公用对象

元数据链接是字典对象,支持引用应用程序容器中所有 PDB 共享的公用元数据并授予其权限。

在 SHARING 子句或 DEFAULT_SHARING 初始化参数中指定 METADATA 值可指定指向对象元数据的链接,称为元数据链接公用对象。对象的元数据在应用程序根中存储一次。

表、视图和代码对象(例如 PL/SQL 过程)可以共享元数据。在此上下文中,“元数据”包括列定义、约束条件、触发器和代码。例如,如果 sales_mlt 是元数据链接公用表,则所有应用程序 PDB 都会通过元数据链接访问此表的相同定义,该定义存储在应用程序根中。sales_mlt 中的行在每个应用程序 PDB 中有所不同,但列定义相同。

通常,应用程序中的大多数对象都将进行元数据链接。因此,只需维护一个主应用程序定义。此方法集中管理多个应用程序 PDB 中的应用程序。

示例 3-2 创建元数据链接的公用对象

在此示例中,SYSTEM 用户登录到 saas_sales_ac 应用程序容器。SYSTEM 在版本 1.0 中安装名为 saas_sales_app 的应用程序。此应用程序创建名为 saas_sales_adm 的公用用户帐户。方案包含一个名为 sales_mlt 的元数据链接公用表。

-- Begin the install of saas_sales_app
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app BEGIN INSTALL '1.0';

-- Create the tablespace for the app
CREATE TABLESPACE saas_sales_tbs DATAFILE SIZE 100M AUTOEXTEND ON NEXT 10M MAXSIZE 200M;

-- Create the user account saas_sales_adm, which will own the app
CREATE USER saas_sales_adm IDENTIFIED BY ****** CONTAINER=ALL;

-- Grant necessary privileges to this user account
GRANT CREATE SESSION, DBA TO saas_sales_adm;

-- Makes the tablespace that you just created the default for saas_sales_adm
ALTER USER saas_sales_adm DEFAULT TABLESPACE saas_sales_tbs;

-- Now connect as the application owner
CONNECT saas_sales_adm/******@saas_sales_ac

-- Create a metadata-linked table
CREATE TABLE saas_sales_adm.sales_mlt SHARING=METADATA
(YEAR       NUMBER(4),
 REGION     VARCHAR2(10),
 QUARTER    VARCHAR2(4),
 REVENUE    NUMBER);

-- End the application installation
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app END INSTALL '1.0';

可以使用 ALTER PLUGGABLE DATABASE APPLICATION ... SYNC 语句同步应用程序 PDB,以使用相同的主应用程序定义。这样,每个应用程序 PDB 都有指向 saas_sales_adm.sales_mlt 公用表的元数据链接。在名为 cust1_pdb 的 PDB 中更新 sales_mlt 的中间层代码在 cust1_pdb 中向此表中添加行,而在 cust2_pdb 中更新 sales_mlt 的中间层代码在 cust2_pdb 中向此表的副本中添加行。仅共享存储在应用程序根中的表元数据。注:Oracle AI Database Security Guide,详细了解授予的对象权限的工作原理

元数据链接

对于元数据链接的应用程序公用对象,对象的元数据将一次存储在应用程序根中。元数据链接是一个字典对象,其对象类型与其共享的元数据相同。

元数据链接的说明存储在创建该链接的 PDB 的数据字典中。元数据链接必须由应用程序公用用户拥有。只能使用元数据链接在 CDB 根或应用程序根中共享其创建者拥有的公用对象的元数据。

与数据链接不同,元数据链接仅依赖于公用数据。例如,如果应用程序在应用程序根中包含本地表 dow_close_lt 和 nasdaq_close_lt,则公用用户无法创建指向这些对象的元数据链接。但是,名为 sales_mlt 的应用程序公用表可以进行元数据链接。

例如,如果特权公用用户更改了 sales_mlt 的元数据,则会将列添加到表中,则此更改将传播到元数据链接。应用程序 PDB 用户不能更改元数据链接中的元数据。例如,管理名为 cust1_pdb 的应用程序 PDB 的 DBA 不能仅向此 PDB 中的 sales_mlt 添加列:此类元数据更改只能在应用程序根中进行。

数据链接的应用程序公用对象

数据链接对象是其元数据和数据位于应用程序根中的对象,可以从此应用程序容器中的所有应用程序 PDB 进行访问。

在 SHARING 子句或 DEFAULT_SHARING 初始化参数中指定 DATA 值可指定指向公用对象的链接,称为数据链接公用对象。数据仓库中的维表通常是数据链接公用表的理想候选项。

数据链接是一个功能与同义词非常相似的字典对象。例如,如果 countries 是应用程序公用表,则所有应用程序 PDB 均可通过数据链接访问此表的相同副本。如果向此表中添加了一行,则该行在所有应用程序 PDB 中都可见。

数据链接必须归应用程序公用用户所有。该链接从它所指向的对象继承对象类型。数据链接的说明存储在创建该链接的 PDB 的字典中。例如,如果应用程序容器包含 10 个应用程序 PDB,并且每个 PDB 都包含指向 countries 应用程序公用表的链接,则所有 10 个 PDB 都包含此链接的字典定义。

示例 3-3 创建数据链接的对象

在此示例中,SYSTEM 连接到 saas_sales_ac 应用程序容器。SYSTEM 将名为 saas_sales_app 的应用程序从版本 1.0 升级到 2.0。此应用程序升级以公用用户 saas_sales_adm 的身份登录容器,创建名为 countries_dlt 的数据链接表,然后向其中插入行。

-- Begin an upgrade of the application
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app BEGIN UPGRADE '1.0' to '2.0';

-- Connect as application owner to application root
CONNECT saas_sales_adm/manager@saas_sales_ac

-- Create data-linked table named countries_dlt
CREATE TABLE countries_dlt SHARING=DATA
(country_id   NUMBER,
 country_name VARCHAR2(20));

-- Insert records into countries_dlt
INSERT INTO countries_dlt VALUES(1, 'USA');
INSERT INTO countries_dlt VALUES(44, 'UK');
INSERT INTO countries_dlt VALUES(86, 'China');
INSERT INTO countries_dlt VALUES(91, 'India');

-- End application upgrade
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app END UPGRADE TO '2.0';

使用 ALTER PLUGGABLE DATABASE APPLICATION ... SYNC 语句将应用程序 PDB 与应用程序根同步。这样,每个同步的应用程序 PDB 都有指向 saas_sales_adm.countries_dlt 数据链接表的数据链接。

扩展的数据链接应用程序对象

扩展数据链接对象是数据链接对象和元数据链接对象的混合。

在扩展数据链接对象中,存储在应用程序根中的数据对所有应用程序 PDB 公用,所有 PDB 都可以访问此数据。但是,在应用程序根中共享公用数据时,每个应用程序 PDB 都可以创建自己的特定于 PDB 的数据。因此,PDB 使用自己的数据补充公用数据。

例如,销售应用程序可能支持多个应用程序 PDB。所有应用程序 PDB 都需要美国的邮政编码。在这种情况下,您可以在应用程序根中创建 zipcodes_edt 扩展数据链接表。应用程序根存储美国的邮政编码,因此所有应用程序 PDB 都可以访问这些邮政编码。但是,一个应用程序 PDB 需要美国和加拿大的邮政编码。此应用程序 PDB 可以在应用程序 PDB 中的扩展数据链接对象(而不是应用程序根)中存储加拿大的邮政编码。

通过连接到应用程序根并在 CREATE 语句中指定 SHARING=EXTENDED DATA 关键字来创建扩展的数据链接对象。

示例 3-4 创建扩展数据对象

在此示例中,SYSTEM 连接到 saas_sales_ac 应用程序容器,然后将名为 saas_sales_app 的应用程序(在“示例 3-2 ”)从版本 2.0 升级到 3.0。此应用程序以公用用户 saas_sales_adm 的身份登录容器,创建名为 zipcodes_edt 的扩展数据链接表,然后向其中插入行。

-- Begin an upgrade of the app
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app BEGIN UPGRADE '2.0' to '3.0';

-- Connect as app owner to app root
CONNECT saas_sales_adm/manager@saas_sales_ac

-- Create a common-data table named zipcodes_edt
CREATE TABLE zipcodes_edt SHARING=EXTENDED DATA
(code       VARCHAR2(5),
 country_id NUMBER,
 region     VARCHAR2(10));

-- Load rows into zipcodes_edt
INSERT INTO zipcodes_edt VALUES ('08820','1','East');
INSERT INTO zipcodes_edt VALUES ('10005','1','East');
INSERT INTO zipcodes_edt VALUES ('44332','1','North');
INSERT INTO zipcodes_edt VALUES ('94065','1','West');
INSERT INTO zipcodes_edt VALUES ('73301','1','South');
COMMIT;

-- End app upgrade
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app END UPGRADE TO '3.0';

使用 ALTER PLUGGABLE DATABASE APPLICATION ... SYNC 语句将应用程序 PDB 与应用程序同步。这样,每个同步的应用程序 PDB 都有指向 saas_sales_adm.zipcodes_edt 数据链接表的数据链接。连接到这些 PDB 的应用程序可以查看在应用程序升级期间插入到 zipcodes_edt 中的邮政编码,但也可以将自己的邮政编码插入到此表中。

容器映射

容器映射可让连接到应用程序根的会话发出 SQL 语句,这些 SQL 语句根据 SQL 语句中使用的谓词值路由到相应 PDB。

映射表指定元数据链接公用表中的列,并使用分区将不同的应用程序 PDB 与不同的列值关联。通过这种方式,如果数据没有在表级别进行物理分区,则容器映射可在 PDB 级别对数据执行分区。

使用容器映射的关键组件包括:

示例 3-5 创建元数据链接的表、映射表和容器映射:第 1 部分

在此示例中,您以应用程序管理员身份登录到应用程序根。假设一个应用程序容器有三个应用程序 PDB:amer_pdb、euro_pdb 和 asia_pdb。每个应用程序 PDB 存储不同区域的国家/地区名称。名为 oe.countries_mlt 的元数据链接表具有存储国家/地区名称的 cname 列。对于此分区策略,可以使用按列表划分的分区来创建名为 salesadm.pdb_map_tbl 的映射对象,该映射对象为每个区域创建一个分区。国家/地区名称确定区域。

ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app BEGIN INSTALL '1.0';

-- Create the metadata-linked table.
CREATE TABLE oe.countries_mlt SHARING=METADATA (
  region    VARCHAR2(30),
  cname     VARCHAR2(30));

-- Create the partitioned map table, which is list partitioned on the
-- cname column. The names of the partitions are the names of the
-- application PDBs.
CREATE TABLE salesadm.pdb_map_tbl (cname VARCHAR2(30) NOT NULL)
  PARTITION BY LIST (cname) (
    PARTITION amer_pdb VALUES ('US','MEXICO','CANADA'),
    PARTITION euro_pdb VALUES ('UK','FRANCE','GERMANY'),
    PARTITION asia_pdb VALUES ('INDIA','CHINA','JAPAN'));

-- Set the CONTAINER_MAP database property to the map object.
ALTER PLUGGABLE DATABASE SET CONTAINER_MAP='salesadm.pdb_map_tbl';

-- Enable the container map for the metadata-linked table to be queried.
ALTER TABLE oe.countries_mlt ENABLE CONTAINER_MAP;

-- Ensure that the table to be queried is enabled for the
-- CONTAINERS clause.
ALTER TABLE oe.countries_mlt ENABLE CONTAINERS_DEFAULT;

-- End the application installation.
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app END INSTALL '1.0';

注:虽然使用分区语法创建容器映射,但数据库不使用分区功能。定义容器映射不需要 Oracle Partitioning。

在前面的脚本中,ALTER TABLE oe.countries_mlt ENABLE CONTAINERS_DEFAULT 语句指定在应用程序根中发出的查询和 DML 语句默认情况下必须对数据库对象使用 CONTAINERS() 子句。

示例 3-6 同步应用程序和添加数据:第 2 部分

此示例从上一个示例继续。连接到应用程序根时,依次将当前容器切换到每个 PDB、同步 saas_sales_app 应用程序,然后将特定于 PDB 的数据添加到 oe.countries_mlt 表。

ALTER SESSION SET CONTAINER=amer_pdb;
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app SYNC;
INSERT INTO oe.countries_mlt VALUES ('AMER','US');
INSERT INTO oe.countries_mlt VALUES ('AMER','MEXICO');
INSERT INTO oe.countries_mlt VALUES ('AMER','CANADA');
COMMIT;

ALTER SESSION SET CONTAINER=euro_pdb;
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app SYNC;
INSERT INTO oe.countries_mlt VALUES ('EURO','UK');
INSERT INTO oe.countries_mlt VALUES ('EURO','FRANCE');
INSERT INTO oe.countries_mlt VALUES ('EURO','GERMANY');
COMMIT;

ALTER SESSION SET CONTAINER=asia_pdb;
ALTER PLUGGABLE DATABASE APPLICATION saas_sales_app SYNC;
INSERT INTO oe.countries_mlt VALUES ('ASIA','INDIA');
INSERT INTO oe.countries_mlt VALUES ('ASIA','CHINA');
INSERT INTO oe.countries_mlt VALUES ('ASIA','JAPAN');
COMMIT;

示例 3-7 查询元数据链接表:第 3 部分

此示例从上一个示例继续。连接到应用程序根,然后多次查询 oe.countries_mlt,在 WHERE 子句中指定不同的国家/地区。该查询从 oe.countries_mlt.region 列返回正确的值。

ALTER SESSION SET CONTAINER=saas_sales_ac;

SELECT region FROM oe.countries_mlt WHERE cname='MEXICO';

REGION
------
AMER

SELECT region FROM oe.countries_mlt WHERE cname='GERMANY';

REGION
------
EURO

SELECT region FROM oe.countries_mlt WHERE cname='JAPAN';

REGION
------
ASIA

跨容器操作

跨容器操作是一次影响多个容器的 DDL 或 DML 语句。

只有连接到 CDB 根或应用程序根的公用用户才能执行跨容器操作。跨容器操作可能会影响:

跨容器 DDL 操作的示例包括:将公用权限授予其他公用用户的用户 SYSTEM,以及应用于整个 CDB 的 ALTER DATABASE . . . RECOVER 语句。

连接到 CDB 根或应用程序根时,可以执行单个 DML 语句来修改容器内多个 PDB 中的表或视图。数据库根据 DML 语句中指定的 CON_ID 列的值推断目标 PDB。如果未指定 CON_ID,则数据库使用 ALTER PLUGGABLE DATABASE CONTAINERS DEFAULT TARGET 语句指定的 CONTAINERS_DEFAULT_TARGET 属性。

示例 3-8 更新单个 DML 语句中的多个 PDB

在此示例中,您的目标是将 country_name 列设置为 sh.sales 表中的值 USA。此表存在于两个单独的 PDB 中,容器 ID 为 7 和 8。这两个 PDB 都位于名为 saas_sales_ac 的应用程序容器中。您可以以管理员身份连接到应用程序根,然后按如下方式进行更新:

CONNECT sales_admin@saas_sales_ac
Password: *******

UPDATE CONTAINERS(sh.sales) sal
  SET sal.country_name = 'USA'
  WHERE sal.CON_ID IN (7,8);

在前面的 UPDATE 语句中,sal 是 CONTAINERS(sh.sales) 的别名。

另请参见:“通用用户账户”