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
Um grande abraço
Otima dica vai ser muito util
Abs