Translate

terça-feira, 1 de abril de 2014

VARRAY e ARRAY

Varray é um conjunto ordenado de elementos de dados. Todos os elementos de um varray são do mesmo tipo de dados. Cada elemento tem um índice, que é um número que corresponde à posição do elemento na matriz. 

Na declaração do Varray é necessário informar a quantidade máxima de elementos que serão armazenados, o valor mínimo é 1. O número de elementos de uma matriz é o tamanho da matriz. Oracle permite matrizes para ser de tamanho variável, que é por isso que eles são chamados varrays.


DECLARE
  --Declara o Varray, define o tamanho máximo e inicializa
  TYPE V_VARRAY IS VARRAY(10) OF VARCHAR2(100);
  L_CAMPEAO V_VARRAY := V_VARRAY( 1958, 1962, 1970, 1994, 2002);

BEGIN
  FOR I IN 1..L_CAMPEAO.COUNT LOOP
    DBMS_OUTPUT.PUT_LINE('O Brasil foi campeão do mundo em: ' ||L_CAMPEAO(I));
  END LOOP;
END;

Resultado: 
O Brasil foi campeão do mundo em: 1958
O Brasil foi campeão do mundo em: 1962
O Brasil foi campeão do mundo em: 1970
O Brasil foi campeão do mundo em: 1994
O Brasil foi campeão do mundo em: 2002

---------------------------------------------------------------

Verificando o tamanho de um Varray

DECLARE

  TYPE coll_method_demo_t IS TABLE OF NUMBER;
  l_loc_var coll_method_demo_t := coll_method_demo_t (10,20,30,40);

BEGIN
  DBMS_OUTPUT.PUT_LINE('O tamanho do Varray é: '||l_loc_var.count);
END;

Resultado:
O tamanho do Varray é:  4

---------------------------------------------------------------

Verificando quantos elementos tem um Varray e quantos poderia ter 

DECLARE

  TYPE coll_method_demo_v IS VARRAY(10) OF NUMBER;
  L_ARRAY1 coll_method_demo_v := coll_method_demo_v (10,20,30,40);

BEGIN
  DBMS_OUTPUT.PUT_LINE('O varray tem '||L_ARRAY1.COUNT||' elementos');
  DBMS_OUTPUT.PUT_LINE('O varray pode ter '||L_ARRAY1.LIMIT||' elementos');  
END;

Resultado:
O varray tem 4 elementos
O varray pode ter 10 elementos

---------------------------------------------------------------
FIRST e LAST

Retornando o primeiro e último elemento de um Array

DECLARE

  TYPE coll_method_demo_t IS TABLE OF NUMBER;
  L_ARRAY coll_method_demo_t := coll_method_demo_t (10,20,30);

BEGIN
  DBMS_OUTPUT.PUT_LINE('Primeiro elemento do array: '|| L_ARRAY (L_ARRAY.FIRST));
  DBMS_OUTPUT.PUT_LINE('Último elemento do array: '|| L_ARRAY (L_ARRAY.LAST));
END;

Resultado:
Primeiro elemento do array: 10
Último elemento do array: 30

---------------------------------------------------------------

ARRAY


Exemplo de um Array (Vetor) (grupo de posições contínuas em memória que possuem o mesmo nome e o mesmo tipo).


DECLARE

  TYPE string_asc_arr_t IS TABLE OF NUMBER
  INDEX BY VARCHAR2(10);
  
  l_str   string_asc_arr_t;
  l_idx   VARCHAR2(50);

BEGIN

  l_str ('Marcelo')   := 9.50;
  l_str ('Juliana')   := 7.5;
  l_str ('Alexandre') := 8;
  l_str ('Luiza')     := 6.5;
  l_str ('Tiago')     := 7;
  l_idx := l_str.FIRST;
  
  WHILE (l_idx IS NOT NULL) LOOP
    DBMS_OUTPUT.PUT_LINE('A nota do(a) '||l_idx||' é '||l_str(l_idx));
    l_idx := l_str.NEXT(l_idx);
  END LOOP;
END;


Resultado:
A nota do(a) Alexandre é 8
A nota do(a) Juliana é 7,5
A nota do(a) Luiza é 6,5
A nota do(a) Marcelo é 9,5
A nota do(a) Tiago é 7

--------------------------------------------------------------

Preenchendo um array automaticamente.

DECLARE

  TYPE RAIZ_QUADRADA_T IS TABLE OF number
  INDEX BY PLS_INTEGER;
  RAIZ_QUADRADA RAIZ_QUADRADA_T;

BEGIN

  FOR I IN 1..100 LOOP    
    raiz_quadrada(I) := SQRT(I);            
  END LOOP;

  -- Mostrando somente os valores desejados:
  DBMS_OUTPUT.PUT_LINE('A raiz quadrada de '||1||' é '|| raiz_quadrada(1)); 
  DBMS_OUTPUT.PUT_LINE('A raiz quadrada de '||2||' é '|| raiz_quadrada(2)); 
  DBMS_OUTPUT.PUT_LINE('A raiz quadrada de '||3||' é '|| raiz_quadrada(3)); 
  DBMS_OUTPUT.PUT_LINE('A raiz quadrada de '||25||' é '|| raiz_quadrada(25)); 
  DBMS_OUTPUT.PUT_LINE('A raiz quadrada de '||40||' é '|| raiz_quadrada(40));    

END;

Resultado:
A raiz quadrada de 1 é 1
A raiz quadrada de 2 é 1,41421356237309504880168872420969807857
A raiz quadrada de 3 é 1,73205080756887729352744634150587236694
A raiz quadrada de 25 é 5
A raiz quadrada de 40 é 6,32455532033675866399778708886543706744

--------------------------------------------------------------

PRIOR e NEXT


DECLARE

  TYPE coll_method_demo_t IS TABLE OF NUMBER;
  L_ARRAY coll_method_demo_t := coll_method_demo_t(12,15,25,32,44,57,68);

BEGIN  
  DBMS_OUTPUT.PUT_LINE('Element before 5th element: '||L_ARRAY(L_ARRAY.PRIOR(6)));
  DBMS_OUTPUT.PUT_LINE('Element after 6th element: '||L_ARRAY(L_ARRAY.NEXT(3)));
END;

Resultado:
Elemento anterior 6º elemento: 44
Elemento posterior 3º elemento: 32

3 comentários:

  1. Boa tarde Marcio, estou com a seguinte situação:

    Tenho a pessoa1 e pessoa2, ambas tem as mesmas colunas com dados diferentes, é possível fazer algo do tipo abaixo:

    for colunas loop
    if pessoa1.coluna != pessoa2.coluna then
    v_diferenca := v_diferenca||' '||coluna||': '||pessoa1.coluna||'-'||pessoa2.coluna;
    end loop

    ResponderExcluir
  2. Consegui fazer marcio, seu post me ajudou muito. abaixo como fiz.

    DECLARE

    TYPE ESTRUTURA IS TABLE OF VARCHAR2(10000 CHAR)
    INDEX BY VARCHAR2(30);

    L_ORIGINAL ESTRUTURA;
    L_MODIFICADO ESTRUTURA;
    L_CHAVE VARCHAR2(30);

    VALOR VARCHAR2(10000 CHAR);

    BEGIN

    FOR DADOS IN (SELECT * FROM PESSOAS) LOOP
    FOR DADOS IN (SELECT C.COLUMN_ID INDICE, C.COLUMN_NAME AS COLUNA FROM COLS C WHERE C.TABLE_NAME = 'PESSOAS' ORDER BY C.COLUMN_ID) LOOP
    EXECUTE IMMEDIATE 'SELECT CASE WHEN '||DADOS.COLUNA||' IS NULL THEN ''NULO'' ELSE TO_CHAR('||DADOS.COLUNA||') END FROM PESSOAS' INTO VALOR;
    L_ORIGINAL(DADOS.COLUNA) := VALOR;
    END LOOP;
    END LOOP;
    L_CHAVE := L_ORIGINAL.FIRST;

    UPDATE PESSOAS P SET P.ATIVO = 'N';

    FOR DADOS IN (SELECT * FROM PESSOAS) LOOP
    FOR DADOS IN (SELECT C.COLUMN_ID INDICE, C.COLUMN_NAME AS COLUNA FROM COLS C WHERE C.TABLE_NAME = 'PESSOAS' ORDER BY C.COLUMN_ID) LOOP
    EXECUTE IMMEDIATE 'SELECT CASE WHEN '||DADOS.COLUNA||' IS NULL THEN ''NULO'' ELSE TO_CHAR('||DADOS.COLUNA||') END FROM PESSOAS' INTO VALOR;
    L_MODIFICADO(DADOS.COLUNA) := VALOR;
    END LOOP;
    END LOOP;

    WHILE (L_CHAVE IS NOT NULL) LOOP
    IF L_ORIGINAL(L_CHAVE) != L_MODIFICADO(L_CHAVE) THEN
    DBMS_OUTPUT.PUT_LINE(L_CHAVE||': '||L_ORIGINAL(L_CHAVE)||' > '||L_MODIFICADO(L_CHAVE));
    END IF;
    L_CHAVE := L_ORIGINAL.NEXT(L_CHAVE);
    END LOOP;
    END;

    ResponderExcluir
    Respostas
    1. Olá Greenomac. Fico feliz que tenha conseguido! Tenho certeza que seu código também ajudara outras pessoas. Grande abraço!

      Excluir