Temos na arquitetura Multitenant a opção de utilizar a cláusula CONTAINERS também em DMLs, permitindo assim que manipulemos dados de múltiplos PDBs. Neste artigo vamos explorar alguns exemplos de uso, onde os objetos pertecem a um Common User.
Coletando informações do ambiente de testes:
[oracle@quiasma ~]$ sqlplus / as sysdba
SQL*Plus: Release 18.0.0.0.0 - Production on Thu Jun 17 05:57:14 2021
Version 18.13.0.0.0
Copyright (c) 1982, 2018, Oracle. All rights reserved.
Connected to:
Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
Version 18.13.0.0.0
SQL> SELECT NAME,OPEN_MODE,CDB FROM V$DATABASE;
NAME OPEN_MODE CDB
--------- -------------------- ---
ASWAN READ WRITE YES
SQL> SHOW PDBS;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 HIPOFISE2 READ WRITE NO
4 HIPOFISE1 READ WRITE NO
SQL> CONN C##LUXOR/oracle
Connected.
SQL> SELECT * FROM CONTAINERS(LOGIN_AUDIT);
RECORD_ID DB USER_ LOGIN_TIM LOGOFF_TI CON_ID
---------- ----- ----- --------- --------- ----------
12 PDB2 USER4 12-JUN-21 12-JUN-21 3
22 PDB2 USER5 12-JUN-21 12-JUN-21 3
32 PDB2 USER4 12-JUN-21 12-JUN-21 3
11 PDB1 USER1 13-JUN-21 13-JUN-21 4
21 PDB1 USER2 13-JUN-21 13-JUN-21 4
31 PDB1 USER3 13-JUN-21 13-JUN-21 4
6 rows selected.
Conectado com o Common User “C##LUXOR” no CDB$ROOT, vamos realizar um insert na tabela apenas no PDB HIPOFISE1 (CON_ID 4):
SQL> SHOW USER;
USER is "C##LUXOR"
SQL> ALTER SESSION SET NLS_DATE_FORMAT='DD-MM-RR HH24:MI';
Session altered.
SQL> INSERT INTO CONTAINERS(LOGIN_AUDIT) (CON_ID, RECORD_ID, DB, USER_ID, LOGIN_TIME, LOGOFF_TIME) VALUES (4,41,'PDB1','USER4', SYSDATE-2.5, SYSDATE-2.4);
1 row created.
SQL> COMMIT;
Commit complete.
SQL> SELECT * FROM CONTAINERS(LOGIN_AUDIT);
RECORD_ID DB USER_ LOGIN_TIME LOGOFF_TIME CON_ID
---------- ----- ----- -------------- -------------- ----------
12 PDB2 USER4 12-06-21 16:47 12-06-21 19:11 3
22 PDB2 USER5 12-06-21 14:23 12-06-21 16:47 3
32 PDB2 USER4 12-06-21 11:59 12-06-21 16:47 3
41 PDB1 USER4 14-06-21 18:01 14-06-21 20:25 4
11 PDB1 USER1 13-06-21 16:46 13-06-21 19:10 4
21 PDB1 USER2 13-06-21 14:22 13-06-21 16:46 4
31 PDB1 USER3 13-06-21 11:58 13-06-21 16:46 4
7 rows selected.
SQL> conn C##LUXOR/oracle
Connected.
SQL> SELECT * FROM CONTAINERS(LOGIN_AUDIT) WHERE CON$NAME IN ('HIPOFISE1') AND RECORD_ID=41;
RECORD_ID DB USER_ LOGIN_TIM LOGOFF_TI CON_ID
---------- ----- ----- --------- --------- ----------
41 PDB1 USER4 14-JUN-21 14-JUN-21 4
Realizando operação de UPDATE também usando o recurso de filtro por PDB:
SQL> UPDATE CONTAINERS(LOGIN_AUDIT) SET USER_ID='TESTE' WHERE CON_ID=4 AND RECORD_ID=41;
1 row updated.
SQL> COMMIT;
Commit complete.
SQL> SELECT * FROM CONTAINERS(LOGIN_AUDIT) WHERE CON$NAME IN ('HIPOFISE1') AND RECORD_ID=41;
RECORD_ID DB USER_ LOGIN_TIM LOGOFF_TI CON_ID
---------- ----- ----- --------- --------- ----------
41 PDB1 TESTE 14-JUN-21 14-JUN-21 4
Por fim, realizando o delete desse registro:
SQL> DELETE CONTAINERS(LOGIN_AUDIT) WHERE CON_ID=4 AND RECORD_ID=41;
1 row deleted.
SQL> COMMIT;
Commit complete.
SQL> SELECT * FROM CONTAINERS(LOGIN_AUDIT) WHERE CON$NAME IN ('HIPOFISE1') AND RECORD_ID=41;
no rows selected
A única coisa interessante é que, na documentação da Oracle, podemos realizar um DML que altere dados de vários PDBs ao mesmo tempo, ou seja, usando o mesmo comando (link AQUI):

Porém, na prática, isso não é possível (aí não é possível saber se é um Bug do RDMS ou da própria documentação):
SQL> UPDATE CONTAINERS(LOGIN_AUDIT) SET USER_ID='TESTE' WHERE CON_ID in (3,4);
UPDATE CONTAINERS(LOGIN_AUDIT) SET USER_ID='TESTE' WHERE CON_ID in (3,4)
*
ERROR at line 1:
ORA-65319: DML on CONTAINERS() specified an unsupported CON_ID predicate
SQL> DELETE CONTAINERS(LOGIN_AUDIT) WHERE CON_ID in (3,4);
DELETE CONTAINERS(LOGIN_AUDIT) WHERE CON_ID in (3,4)
*
ERROR at line 1:
ORA-65319: DML on CONTAINERS() specified an unsupported CON_ID predicate
Obs: Este procedimento foi criado pelo senhor Ahmed Baraka (www.ahmedbaraka.com) e foi apenas reproduzido por mim em um laboratório pessoal para fins de aprendizado.