Com o parâmetro “CONTAINERS_DEFAULT_TARGET” conseguimos definir o valor padrão de container que podemos nos usufruir ao rodar comandos de DML, conforme este artigo reproduzirá.
Fazendo reconhecimento do ambiente de laboratório usado:
[oracle@quiasma ~]$ sqlplus / as sysdba
SQL*Plus: Release 18.0.0.0.0 - Production on Thu Jun 17 20:45:37 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
Ao consultar qual é o valor atual do parâmetro, vemos que o mesmo está vazio, o que significa que, ao rodar algum comando, o container padrão adotado será o current container:
SQL> SELECT PROPERTY_VALUE FROM DATABASE_PROPERTIES WHERE PROPERTY_NAME='CONTAINERS_DEFAULT_TARGET';
no rows selected
Dito isto, vamos validar se a parte prática acompanha a teórica. Abaixo segue uma tabela que existe em 3 containers (CDB$ROOT, HIPOFISE1 e HIPOFISE2):
SQL> conn C##LUXOR/oracle
Connected.
SQL> SELECT * FROM CONTAINERS(LOGIN_AUDIT);
RECORD_ID DB USER_ LOGIN_TIM LOGOFF_TI CON_ID
---------- ----- ----- --------- --------- ----------
66 ROOT BSS 15-JUN-21 15-JUN-21 1
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
7 rows selected.
Mudando sessão para o PDB HIPOFISE1 e realizando um UPDATE sem mencionar o container (para que o current seja considerado e usado):
SQL> ALTER SESSION SET CONTAINER=HIPOFISE1;
Session altered.
SQL> UPDATE CONTAINERS(LOGIN_AUDIT) SET USER_ID='XXX';
3 rows updated.
SQL> SELECT USER_ID FROM LOGIN_AUDIT;
USER_
-----
XXX
XXX
XXX
SQL> SELECT * FROM CONTAINERS(LOGIN_AUDIT);
RECORD_ID DB USER_ LOGIN_TIM LOGOFF_TI CON_ID
---------- ----- ----- --------- --------- ----------
11 PDB1 XXX 13-JUN-21 13-JUN-21 4
21 PDB1 XXX 13-JUN-21 13-JUN-21 4
31 PDB1 XXX 13-JUN-21 13-JUN-21 4
SQL> ROLLBACK;
Rollback complete.
SQL> SELECT USER_ID FROM LOGIN_AUDIT;
USER_
-----
USER1
USER2
USER3
Agora vamos definir o valor do PDB que será considerado como padrão:
SQL> conn / as sysdba
Connected.
SQL> ALTER DATABASE CONTAINERS DEFAULT TARGET = (HIPOFISE2);
Database altered.
Podemos perceber que o preenchimento acontece com o DBID, e não o nome do PDB:
SQL> SELECT PROPERTY_VALUE FROM DATABASE_PROPERTIES WHERE PROPERTY_NAME='CONTAINERS_DEFAULT_TARGET';
PROPERTY_VALUE
--------------------------------------------------------------------------------
1961048788
SQL> SELECT NAME, DBID, CON_UID FROM V$PDBS WHERE NAME='HIPOFISE2';
NAME
--------------------------------------------------------------------------------
DBID CON_UID
---------- ----------
HIPOFISE2
1961048788 1961048788
Agora faremos a DML sem informar o PDB, para validar que o HIPOFISE2 foi utilizado com sucesso:
SQL> UPDATE CONTAINERS(LOGIN_AUDIT) SET USER_ID='XXX';
3 rows updated.
SQL> COMMIT;
Commit complete.
SQL> SELECT USER_ID FROM LOGIN_AUDIT;
USER_
-----
BSS
SQL> SELECT USER_ID FROM CONTAINERS(LOGIN_AUDIT) WHERE CON_ID=3;
USER_
-----
XXX
XXX
XXX
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.