VARRAY, TYPE RECORD ou os dois?

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 319
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Senhores,

É uma imensa satisfação poder voltar a interagir com os membros desse fórum que me ajudaram muito no passado e em começo de carreira. Depois de um tempo, comecei a retribuir toda a ajuda prestada, participando ativamente do fórum e podendo auxiliar outros colegas. É muito bom saber que este espaço continua ativo e com certeza contribuindo para o crescimento e evolução de muitos.

Fiquei um tempo afastado do PL/SQL e estou meio enferrujado. Na verdade até já consegui fazer o que eu preciso. Só gostaria de esclarecer uma dúvida sobre a diferença e qual a melhor abordagem para retornar uma COLLECTION através de um FUNCTION. Para isso, peguei um exemplo que achei na internet e fiz algumas alterações para ilustrar, conforme abaixo:

Selecionar tudo


DECLARE
  TYPE array_t IS VARRAY(2) OF CHAR;

  data array_t;

  FUNCTION func 
    RETURN array_t IS
    
    l1 char(1);
    l2 char(1);
    
  BEGIN
    select 'a' as "A", 'b' as "B" 
      into l1, l2
      from dual;
    
    RETURN array_t( l1, l2);
  END func;
BEGIN
  data := func();
  DBMS_OUTPUT.PUT_LINE( '(' || data(1) || ', ' || data(2) || ')' );
END;

Isso aqui, já da certo para o que eu preciso. Dúvidas:

- Eu não consigo popular o array diretamente no INTO?;

Existe uma outra abordagem onde é criado um RECORD com a estrutura e datatype da tabela que preciso retornar e o array por usa vez tem como tipo o RECORD, assim:

Selecionar tudo

DECLARE
  idx number := 0;
  type rec_type is record ( c1 char(1)
                           ,c2 char(1) );
                          
--  rec rec_type;
  TYPE arr_rec IS VARRAY(2) OF rec_type;
    data arr_rec;
  
  rec_table arr_rec := arr_rec(); 

  FUNCTION func 
    RETURN arr_rec IS
    
/*    l1 char(1);
    l2 char(1);*/

    l1 number := 1;
    l2 number := 2;
    
  BEGIN
    rec_table.extend(2);
    
/*    select 'a' as "A", 'b' as "B" 
      into l1, l2
      from dual;*/
      
    rec_table(1) := rec_table(l1);
    rec_table(2) := rec_table(l2);
      
      return rec_table;
      
  END func;
BEGIN
  data := func();
  
/*  for idx in data.first..data.last
  loop
    dbms_output.put_line( data(idx) );
  end loop;*/
  
  DBMS_OUTPUT.PUT_LINE('teste');
exception
  when others then
    DBMS_OUTPUT.PUT_LINE(sqlcode || ' - ' || sqlerrm);
END;

No exemplo acima, tanto meu RECORD quanto o meu VARRAY, inicialmente eles são declarados como sendo do tipo CHAR, porém ao tentar atribuir os valores retornado pelo "SELECT" está dando o erro de conversão de tipo:
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
Por isso, fiz um teste mudando os dados de CHAR para NUMBER e funcionou.

Aqui surgem outras dúvidas, como:

- Por que está dando esse erro de conversão sendo que todos os dados envolvidos são do mesmo tipo?

- Em quais situações é recomendado utilizar o TYPE RECORD e criar um ARRAY do tipo de dados desse RECORD? Existe alguma vantagem/benefício em utilizar essa abordagem?

No mais, agradeço a atenção de todos que puderem ajudar.

Abs.
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 11 visitantes