jueves, 6 de septiembre de 2007

ANYDATA

En Oracle 9i se agregó un nuevo tipo de dato: ANYDATA. Normalmente, creamos un campo DATE para guardar fechas, un campo VARCHAR2 para guardar texto, un campo NUMBER para guardar números... pero qué sucede si mi aplicación guarda datos genéricos? Es decir, qué sucede si mi aplicación guarda en un mismo campo valores de distinto tipo de dato? En éste tipo de casos nos convendría usar el tipo de dato ANYDATA.

Veamos un ejemplo:

SQL_9iR2> CREATE TABLE test ( algo sys.anyData ) ;

Table created.

SQL_9iR2> INSERT INTO test VALUES ( sys.anyData.ConvertVarchar2('esto es
un ejemplo') ) ;

1 row created.

SQL_9iR2> INSERT INTO test VALUES ( sys.anyData.ConvertDate(sysdate) ) ;

1 row created.

SQL_9iR2> INSERT INTO test VALUES ( sys.anyData.ConvertNumber(1000) ) ;

1 row created.

Si consultamos la tabla (como lo hariamos de forma tradicional), no vemos los datos... simplemente vemos el tipo ANYDATA...

SQL_9iR2> SELECT *
2 FROM test ;

ALGO()
-----------------
ANYDATA()
ANYDATA()
ANYDATA()

3 rows selected.

SQL_9iR2> DESC test
Name Null? Type
------------------------- -------- --------------
ALGO SYS.ANYDATA

Antes de mostrarles cómo ver los datos reales de la tabla... Veamos los tipos de cada dato...

SQL_9iR2> SELECT anyData.gettypeName(algo) TipoDeDato
2 FROM test ;

TIPODEDATO
-----------------
SYS.VARCHAR2
SYS.DATE
SYS.NUMBER

3 rows selected.

Lamentablemente, no es tan fácil ver los datos de la tabla. Pero porqué no es fácil? Porque está pensando para ser utilizado dentro de un procedimiento en donde se hace el fetch de los datos y luego se los convierte y procesa. Entonces veamos... Para ver los datos reales de la tabla, vamos a construir un package con 3 funciones. Cada una de esas funciones se va a encargar de convertir un tipo de dato y devolvernos el valor de la conversión:

SQL_9iR2> CREATE OR REPLACE PACKAGE pkg_convertir_anydata AS
2
3 FUNCTION convertir_varchar2 ( p_dato IN sys.anydata ) RETURN VARCHAR2 ;
4 FUNCTION convertir_date ( p_dato IN sys.anydata ) RETURN DATE ;
5 FUNCTION convertir_number ( p_dato IN sys.anydata ) RETURN NUMBER ;
6
7 END pkg_convertir_anydata ;
8 /

Package created.

SQL_9iR2> CREATE OR REPLACE PACKAGE BODY pkg_convertir_anydata AS
2
3 FUNCTION convertir_varchar2 ( p_dato IN sys.anydata ) RETURN VARCHAR2 IS
4 nada NUMBER ;
5 l_varchar2 VARCHAR2(4000) ;
6 BEGIN
7 nada := p_dato.GetVarchar2( l_varchar2 ) ;
8 RETURN ( l_varchar2 ) ;
9 END ;
10
11 FUNCTION convertir_date ( p_dato IN sys.anydata ) RETURN DATE IS
12 nada NUMBER ;
13 l_date DATE ;
14 BEGIN
15 nada := p_dato.GetDate( l_date ) ;
16 RETURN ( l_date ) ;
17 END ;
18
19 FUNCTION convertir_number ( p_dato IN sys.anydata ) RETURN NUMBER IS
20 nada NUMBER ;
21 l_number NUMBER ;
22 BEGIN
23 nada := p_dato.GetNumber ( l_number ) ;
24 RETURN ( l_number ) ;
25 END ;
26
27 END pkg_convertir_anydata ;
28 /

Package body created.

Lo único que nos resta por hacer es construir la consulta para convertir y mostrar nuestros datos:

SQL_9iR2> WITH Datos AS
2 ( SELECT algo , sys.anydata.gettypename(algo) TipoDeDato FROM test )
3 SELECT CASE
4 WHEN TipoDeDato = 'SYS.VARCHAR2' THEN
5 TO_CHAR(pkg_convertir_anydata.convertir_Varchar2(algo))
6 WHEN TipoDeDato = 'SYS.DATE' THEN
7 TO_CHAR(pkg_convertir_anydata.convertir_Date(algo),'dd-mon-
rrrr hh24:mi:ss')
8 WHEN TipoDeDato = 'SYS.NUMBER' THEN
9 TO_CHAR(pkg_convertir_anydata.convertir_Number(algo))
10 END algo
11 FROM Datos ;

ALGO
--------------------------
esto es un ejemplo
06-sep-2007 21:49:37
1000


3 rows selected.

No hay comentarios.: