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

PL/SQL – Você conhece o ANYDATA ?

Olá pessoal !

Depois de observar que poucos developers PL/SQL o conhecem, decidi escrever sobre o ANYDATA.

A partir do Oracle 9i, a Oracle introduziu esse novo type. Como o próprio nome diz, uma variável ANYDATA pode simplesmente conter a instância de um determinado type, ou mesmo um conjunto deles (Collections). Inclusive, pode ser persistido no próprio banco de dados (menos External LOBs, conhecidos também como BFILES).

A conversão de outros types para ANYDATA é feita através de funções próprias. Abaixo um exemplo de como criar uma tabela com um campo ANYDATA e inserir dados nela.

CREATE TABLE anydata_test
(
 field ANYDATA
)
/

INSERT INTO anydata_test
VALUES
   (
    SYS.ANYDATA.convertDate(SYSDATE)
   )
/

INSERT INTO anydata_test
VALUES
   (
    SYS.ANYDATA.convertNumber(5)
   )
/

INSERT INTO anydata_test
VALUES
   (
    SYS.ANYDATA.convertVarchar2('TESTE ANYDATA')
   )
/

Utilizei três types básicos (DATE, NUMBER e VARCHAR2). Observe que cada um dos tipos tem uma função específica para conversão.

Vamos executar um simples SELECT na tabela que criamos, para ver o resultado:

SELECT a.field
FROM   anydata_test a
/

Como podem observar, os dados não se revelam aos se efetuar um simples SELECT. É preciso converter os dados para os seus respectivos types para que vejamos o real conteúdo.

Vejamos qual os tipos que estão armazenados no campo ANYDATA (finja que não sabe). A função getTypeName exibe qual o tipo armazenado.

SELECT a.field.getTypeName() type
FROM   anydata_test a
/

Agora sabemos que temos 3 types diferentes em nossa tabela. Vamos montar uma pequena função para que nos exiba os resultados contidos no campo FIELD.

CREATE OR REPLACE
FUNCTION getAnyData
            (
             pField SYS.ANYDATA
            )
RETURN VARCHAR2           
AS
  fieldVarchar2 VARCHAR2(2000);
  fieldDate     DATE;
  fieldNumber   NUMBER;

BEGIN
   IF  pField.getTypeName           = 'SYS.NUMBER'
   AND pField.getNumber(fieldNumber)= DBMS_TYPES.SUCCESS
   THEN
      RETURN(TO_CHAR(fieldNumber));

   ELSIF pField.getTypeName       = 'SYS.DATE'
   AND   pField.getDate(fieldDate)= DBMS_TYPES.SUCCESS
   THEN
      RETURN(TO_CHAR(fieldDate));

   ELSIF pField.getTypeName               = 'SYS.VARCHAR2'
   AND   pField.getVarchar2(fieldVarchar2)= DBMS_TYPES.SUCCESS
   THEN
      RETURN(TO_CHAR(fieldVarchar2));

   ELSE
      RETURN NULL;

   END IF; 

END getAnyData;

Em uma rápida explicação, utilizamos o getTypeName() para descobrir o tipo e fazemos a conversão utilizando getNumber(), getDate() e getVarchar2(). Se o resultado for o valor de DBMS_TYPES.SUCCESS , significa que a conversão foi bem sucedida. Então retornamos o valor contido nas variáveis fieldNumber, fieldDate e fieldVarchar2 respectivamente.

Executemos agora o nosso SELECT, utilizando a função que criamos.

SELECT getAnyData(a.field) field
FROM   anydata_test a
/

Pronto ! Todos os dados contidos no campo Field, agora estão a nossa disposição.

Você pode se perguntar sobre qual a utilidade do ANYDATA. Sendo que você pode criar as tabelas com os types correspondentes aos tipos e não depender de funções e conversões.

Garanto que é muito útil ! Existem inúmeras situações em que o ANYDATA é indispensável. E não estou falando de apenas persistir em banco, mas de transporte de collections, parâmetros…entre outras coisas.

Só que isso é objeto para um outro artigo, pois a ideia central desse, é apresentar a existência desse type.

Prometo que escreverei sobre um exemplo prático no próximo !

Referências

https://docs.oracle.com/cd/B19306_01/appdev.102/b14258/t_anydat.htm#BEHEICHI

Um grande abraço

Share

You may also like...

Deixe um comentário

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