Temos um recurso nativo na arquitetura Multitenant de podermos consultar os dados de tabelas/views de common users de múltiplos PDBs ao mesmo tempo. Porém, qual seria a nossa opção caso esses objetos tivessem como owner Local Users, em vez de Common Users? Este artigo tentará explorar uma alternativa para esta situação.
Validando PDBs existentes em meu laboratório:
[oracle@quiasma ~]$ sqlplus / as sysdba
SQL*Plus: Release 18.0.0.0.0 - Production on Tue Jun 15 05:31:12 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
Validando Local User chamado BSS1, no PDB HIPOFISE1, e a tabela que usaremos como referência de teste:
SQL> ALTER SESSION SET CONTAINER=HIPOFISE1;
Session altered.
SQL> SELECT USERNAME,COMMON FROM DBA_USERS WHERE USERNAME='BSS1';
USERNAME
--------------------------------------------------------------------------------
COM
---
BSS1
NO
SQL> DESC BSS1.TESTE1;
Name Null? Type
----------------------------------------- -------- ----------------------------
DESCRICAO VARCHAR2(20)
SQL> SELECT * FROM BSS1.TESTE1;
DESCRICAO
--------------------
PDB HIPOFISE1
Validando Local User chamado BSS, no PDB HIPOFISE2, e a tabela que usaremos como referência de teste:
SQL> ALTER SESSION SET CONTAINER=HIPOFISE2;
Session altered.
SQL> SELECT USERNAME,COMMON FROM DBA_USERS WHERE USERNAME='BSS';
USERNAME
--------------------------------------------------------------------------------
COM
---
BSS
NO
SQL> DESC BSS.TESTE;
Name Null? Type
----------------------------------------- -------- ----------------------------
DESCRICAO VARCHAR2(20)
SQL> SELECT * FROM BSS.TESTE;
DESCRICAO
--------------------
PDB HIPOFISE2
Uma alternativa para este cenário seria: conectarmos em cada PDB com um Common User, e criarmos uma view consultando as tabelas referidas. Vamos realizar essa etapa no primeiro PDB:
SQL> conn C##LUXOR/oracle
Connected.
SQL> ALTER SESSION SET CONTAINER=HIPOFISE1;
Session altered.
SQL> CREATE VIEW C##LUXOR.VIEW_DO_BRUNO AS SELECT * FROM BSS1.TESTE1;
View created.
SQL> SELECT * FROM C##LUXOR.VIEW_DO_BRUNO;
DESCRICAO
--------------------
PDB HIPOFISE1
Criando View no segundo PDB:
SQL> conn C##LUXOR/oracle
Connected.
SQL> ALTER SESSION SET CONTAINER=HIPOFISE2;
Session altered.
SQL> CREATE VIEW C##LUXOR.VIEW_DO_BRUNO AS SELECT * FROM BSS.TESTE;
View created.
SQL> SELECT * FROM C##LUXOR.VIEW_DO_BRUNO;
DESCRICAO
--------------------
PDB HIPOFISE2
Agora podemos uma tabela no CDB$ROOT com a mesma estrutura das views:
SQL> conn C##LUXOR/oracle
Connected.
SQL> CREATE TABLE C##LUXOR.VIEW_DO_BRUNO (DESCRICAO VARCHAR2(20));
Table created.
Realizando consulta em todos os PDBs a partir do CDB$ROOT:
SQL> SELECT * FROM CONTAINERS(VIEW_DO_BRUNO);
DESCRICAO CON_ID
-------------------- ----------
PDB HIPOFISE2 3
PDB HIPOFISE1 4
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.