GPO ( Grupo de Profissionais Oracle )
A maior comunidade Oracle do Brasil !

PL/SQL – Armazenando um collection no banco de dados com ANYDATA

Olá pessoal !

Aqui estou novamente falando sobre ANYDATA, como prometido no artigo anterior. Quando comecei a escrever o primeiro texto, a idéia era que o assunto se prolongasse por apenas um mais. Isso mudou quando percebi que poderia mostrar alguns truques que também poderiam ser feitos usando ANYDATA, portanto, a série ainda terá um terceiro artigo ! 🙂

Hoje irei demonstrar em como persistir o resultado de uma collection no banco de dados. Resumindo, vou guardar o resultado de um SELECT em um registro de uma tabela.

Primeiro, vamos criar os types que nos auxiliarão nessa empreitada. Eles serão a estrutura dos dados que serão persistidos. Também criaremos a tabela no banco de dados.

-- Type que será o “registro”

CREATE OR REPLACE TYPE tData AS OBJECT
   (
    code    NUMBER
   ,description VARCHAR2(100)
   )
/       

-- Type que será a “tabela” contendo os “registros”

CREATE OR REPLACE TYPE tTableData AS TABLE OF tData
/

-- Tabela que conterá os dados 

CREATE TABLE anydata_result
(
 code    NUMBER,
 result  ANYDATA
)
/

Com a estrutura para armazenamento dos dados pronta, vamos agora criar a nossa procedure de teste. Ela fará a leitura dos dados, armazenará e depois fará a leitura da collection armazenada.

CREATE OR REPLACE PROCEDURE proc_anydata_test IS
   tableData    tTableData;       
   vAnyData    ANYDATA;
   vDummy      NUMBER;

BEGIN  
   FOR z IN 1..3 LOOP
      DBMS_OUTPUT.PUT_LINE('Armazena e lê registro de número: ' || z);

      -- Retorna Collection com o Resultado

      BEGIN
          SELECT tData(x.code,x.description)
          BULK COLLECT INTO tableData
          FROM
          (
            SELECT 1 code,'RESULTADO 1' description FROM DUAL
            UNION
            SELECT 2 code,'RESULTADO 2' description FROM DUAL
            UNION
            SELECT 3 code,'RESULTADO 3' description FROM DUAL
          ) x
          WHERE x.code <= z;

      EXCEPTION
         WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE('READ DATA [ FAILED ] - ' || DBMS_UTILITY.FORMAT_ERROR_STACK); 

      END;  

      -- Converte Table para ANYDATA

      vAnyData := ANYDATA.convertCollection(tableData);

      -- Insere os dados na tabela

     BEGIN
        INSERT INTO anydata_result
        VALUES (z,vAnyData);
        COMMIT; 

     EXCEPTION
        WHEN OTHERS THEN
           DBMS_OUTPUT.PUT_LINE('INSERT DATA [ FAILED ] - ' || DBMS_UTILITY.FORMAT_ERROR_STACK);       

     END;  

     -- Lê o registro com a tabela

     BEGIN
        SELECT y.result
        INTO   vAnyData
        FROM   anydata_result y
        WHERE  y.code = z;
 
     EXCEPTION
         WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE('READ DATA [ FAILED ] - ' || DBMS_UTILITY.FORMAT_ERROR_STACK);       

     END;  

     -- Converte AnyData para Table

      vDummy := vAnyData.getCollection(tableData);

     -- Lê a Tabela

     FOR x IN tableData.FIRST..tableData.LAST LOOP
        DBMS_OUTPUT.PUT_LINE('Codigo: ' || tableData(x).code || ' - Descricao : ' || tableData(x).description);
  
     END LOOP;

  END LOOP;

EXCEPTION
   WHEN OTHERS THEN         
      DBMS_OUTPUT.PUT_LINE('proc_anydata_test [ FAILED ] - ' || DBMS_UTILITY.FORMAT_ERROR_STACK);

END proc_anydata_test;

Basicamente a PROCEDURE pode ser dividida em:

– Leitura e armazenamento da collection em uma variável (tableData);
– Conversão do TABLE para ANYDATA;
– Inserção dos dados na tabela (anydata_result);
– Leitura dos dados na tabela (anydata_result);
– Conversão de ANYDATA para TABLE;
– Leitura da Collection;

Vamos agora executar nossa procedure…

BEGIN
   proc_anydata_test;

END;

E o resultado é:

SQL>

1 Armazena e lê registro de número: 1
2 Codigo: 1 - Descricao : RESULTADO 1
3 Armazena e lê registro de número: 2
4 Codigo: 1 - Descricao : RESULTADO 1
5 Codigo: 2 - Descricao : RESULTADO 2
6 Armazena e lê registro de número: 3
7 Codigo: 1 - Descricao : RESULTADO 1
8 Codigo: 2 - Descricao : RESULTADO 2
9 Codigo: 3 - Descricao : RESULTADO 3

Na primeira vez que o loop é executado, a collection tem apenas 1 registro, o segundo 2 e o terceiro respectivamente 3 ! 🙂

Vamos dar uma olhada no que foi armazenado no banco através de um SELECT simples…

SELECT * FROM  anydata_result
/

Como podem observar, as aplicações de ANYDATA podem ser das mais variadas. No próximo artigo, vamos fazer algo ainda mais interessante !

Um grande abraço

Share

You may also like...

Deixe um comentário

O seu endereço de e-mail não será publicado.