Pular para o conteúdo

Criando variáveis ? Utilize o Associative Array

Criando variáveis ? Utilize o Associative Array

Sergio,
estou dando manutenção em um sistema que tem dezenas de variáveis v_ criadas para cálculo e acho que não é uma boa prática. Como poderia mudar isso ?

V.


Então, eu também não sou muito fã de sair criando dezenas de variáveis, pois isso envolve tipificar cada uma, atribuir e tudo o mais que envolve uma operação básica que as utiliza. Quando os campos são utilizados para inserção e são compatíveis com um ROWTYPE, fica muito mais fácil utilizar uma variável desse tipo, inclusive, escrevi sobre isso no artigo abaixo:

https://www.profissionaloracle.com.br/2014/03/04/utilizando-rowtype-parte-i/

Infelizmente essa abordagem não atende a todas as necessidades, mas sempre podemos contar com o Associative Array.

Primeiramente, vamos montar um exemplo onde precisamos separar valores por tipo de pagamento. Vamos criar uma tabela chamada PAGAMENTOS. Será uma tabela desnormalizada e simples só para exemplificarmos.

CREATE TABLE pagamentos
(
 tipo_pagamento VARCHAR2(150)
,valor          NUMBER   
)
/

Table PAGAMENTOS created.

Agora vamos inserir alguns dados:

INSERT INTO pagamentos VALUES ('CARTÃO DE CRÉDITO',150)
/
INSERT INTO pagamentos VALUES ('CARTÃO DE CRÉDITO',100)
/
INSERT INTO pagamentos VALUES ('CARTÃO DE CRÉDITO',50)
/
INSERT INTO pagamentos VALUES ('DINHEIRO',70)
/
INSERT INTO pagamentos VALUES ('DINHEIRO',170)
/
INSERT INTO pagamentos VALUES ('DINHEIRO',10)
/
INSERT INTO pagamentos VALUES ('CARTÃO DE DÉBITO',80)
/
INSERT INTO pagamentos VALUES ('CARTÃO DE DÉBITO',90)
/
INSERT INTO pagamentos VALUES ('CARTÃO DE DÉBITO',200)
/
INSERT INTO pagamentos VALUES ('CARTÃO DE DÉBITO',100)
/
INSERT INTO pagamentos VALUES ('CARTÃO DE DÉBITO',105)
/

Vamos criar um bloco anônimo que irá somar os valores de acordo com o tipo de pagamento.

DECLARE
   -- Type based variable and index

   TYPE value_table IS TABLE OF NUMBER INDEX BY VARCHAR2(50);
   v_value_table      value_table;
   v_key              VARCHAR2(50);

   -- Cursor

   CURSOR c_pagamentos
      IS
         SELECT x.tipo_pagamento
               ,x.valor
         FROM  pagamentos x;

   r_pagamentos c_pagamentos%ROWTYPE;   

   --
   -- Increment values
   --   
   PROCEDURE save_values
                (
                 p_value_type IN VARCHAR2
                ,p_value      IN NUMBER
                )
   AS             
   BEGIN
      v_value_table(p_value_type) := v_value_table(p_value_type) + NVL(p_value,0);

   EXCEPTION
      WHEN no_data_found THEN
         -- Se não existir o índice atual, atribui o valor
         v_value_table(p_value_type) := NVL(p_value,0);

   END save_values;  

 BEGIN
    -- Limpa a tabela
    v_value_table.DELETE;
   
    -- Soma os valores de acordo com o tipo de pagamento
    FOR r_pagamentos IN c_pagamentos
    LOOP
       save_values(R_PAGAMENTOS.tipo_pagamento, R_PAGAMENTOS.valor);
 
    END LOOP;

    -- Lê os resultados
    v_key := v_value_table.FIRST;

    WHILE v_Key IS NOT NULL
    LOOP
       DBMS_OUTPUT.put_line('[ CHAVE ] ' || RPAD(v_key,20) ||' [ VALOR ] ' || v_value_table(v_key));
       v_key := v_value_table.NEXT(v_Key);

    END LOOP; 
 
    -- Buscando os valores pelo índice
    DBMS_OUTPUT.put_line('[ VALOR ] ' || v_value_table('DINHEIRO'));
    DBMS_OUTPUT.put_line('[ VALOR ] ' || v_value_table('CARTÃO DE DÉBITO'));
    DBMS_OUTPUT.put_line('[ VALOR ] ' || v_value_table('CARTÃO DE CRÉDITO'));

    -- Somando os cartões
    save_values('CARTÃO',v_value_table('CARTÃO DE CRÉDITO') + v_value_table('CARTÃO DE DÉBITO'));
    DBMS_OUTPUT.put_line('[ VALOR CARTÃO ] ' || v_value_table('CARTÃO'));   

END;

Executando…

PL/SQL procedure successfully completed.

[ CHAVE ] CARTÃO DE CRÉDITO    [ VALOR ] 300
[ CHAVE ] CARTÃO DE DÉBITO     [ VALOR ] 575
[ CHAVE ] DINHEIRO             [ VALOR ] 250
[ VALOR ] 250
[ VALOR ] 575
[ VALOR ] 300
[ VALOR CARTÃO ] 875

Veja que apesar de eu ter incluído índices de acordo com a leitura da tabela, eu também criei manualmente a entrada CARTÃO para salvar os valores somados de DÉBITO e CRÉDITO.

Com apenas quatros valores a serem guardados e computados, pode não parecer valer a pena utilizar um Associative Array, mas imagine quando falamos de 10 ou 20 deles.

Espero ter ajudado !

Sergio Willians

Sergio Willians

Sergio Willians é o fundador do GPO (Grupo de Profissionais Oracle) e possui quase 30 anos de experiência em tecnologias Oracle, sendo especialista em desenvolvimento Forms/Reports, PL/SQL e EBS (E-Business Suite) nos módulos Receivables, Payables e General Ledger. Atualmente trabalha na Scania Latin America, onde se dedica à área de integração de dados com Confluent Kafka. Sua paixão é compartilhar conhecimento com a comunidade Oracle, contribuindo para o crescimento e a excelência da plataforma.

Comentário(s) da Comunidade

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

plugins premium WordPress