Querying data owned by Local users Across All PDBs

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.

Leave a Comment

Your email address will not be published.