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:
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 !

Formado em Gestão em Tecnologia da Informação, com sólidos conhecimentos em SQL, PL/SQL, Oracle Forms, Reports e E-Business Suite (AP,AR e GL).
Foi durante 3 anos gerente de tecnologia de grande empresa do setor de saúde, e atualmente atua como Analista de Sistema Sênior na Scania Latin America e também como Diretor-fundador do GPO (Grupo de Profissionais Oracle).
boa explicaçao