martes, 20 de octubre de 2009

Pasar un Array a un Stored Procedure en Oracle

Durante estos días tuve que hacer la prueba de pasar un array como parámetro a un Stored Procedure en un Oracle 8i desde Java. Al principio pense que era una tarea simple, pero luego encontre que no es tan así dado que me tope con 3 problemas que trataré de describir aquí.

Pero primero dejo dos URL que tienen información de como hacer esto:
* Muy buen foro
* Documentación Oficial de Oracle

Como mencione, al principio pense que usando JDBC podría lograr esto sin tener problemas pero me encontre con algunas limitaciones de JDBC y el tratamiento de los Array, así que tuve que trabajar directamente usando clases propietarias de Oracle. Quedando un código:


DriverManager.registerDriver(new OracleDriver());

String url = "jdbc:oracle:thin:@10.65.72.52:1521:BNPAIS";
Connection conn = DriverManager.getConnection(url, "*******", "*******");

String[] array = {"hola", "mundo"};

ArrayDescriptor descriptor =
ArrayDescriptor.createDescriptor( "T_LISTAVARCHAR2", conn );
ARRAY array_to_pass =
new ARRAY( descriptor, conn, array);

CallableStatement ps = conn.prepareCall("{call TEST.TEST_ARRAY(?,?)}");
ps.setArray(1, array_to_pass);
ps.registerOutParameter(2, OracleTypes.VARCHAR);

ps.execute();

System.out.println( ps.getString(2) );

conn.close();


Ya en la base de datos, primero declaré el tipo de dato ARRAY que use para la prueba (un ARRAY de VARCHAR). Aquí tenia dos opciones, o bien declararlo dentro del package donde iba a tener mi SP o a nivel del schema.
CREATE OR REPLACE TYPE t_listavarchar2 IS TABLE OF varchar2(300)


Opte por la primer opción y enseguida me encontre con el sigueinte error:
java.sql.SQLException: invalid name pattern:


Basicamente, no me encontraba el tipo de dato declarado.:
ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor( "T_LISTAVARCHAR2", conn );


Buscando la solución encontré 2 soluciones posibles, una (la mas simple) es declarar el tipo de datos a nivel del esquema y la otra es crear un sinónimo publico para el tipo (T_LISTAVARCHAR2) con los accesos y permisos correspondientes al usuario que intente acceder.

Una vez solucionado este problema, me encontre por un par de errores de NoClassDefFoundError por falta de algunos JARs. Para solucionarlo además de classes12.jar puse en mi classpath: nls_charset12.jar

Además aquí dejo otro link con información valiosa sobre los jar a colocar en nuestro classpath.

La verdad que no fue complicado, pero tampoco fue tan simple como esperaba.

lunes, 5 de octubre de 2009

Typical Web Architecture.

In computer security, a demilitarized zone, named after the military usage of the term and normally abbreviated to DMZ; also known as a Data Management Zone or Demarcation Zone or Perimeter Network, is a physical or logical subnetwork that contains and exposes an organization's external services to a larger, untrusted network, usually the Internet. The purpose of a DMZ is to add an additional layer of security to an organization's Local Area Network (LAN); an external attacker only has access to equipment in the DMZ, rather than the whole of the network.

See more: DMZ - Wikipedia

A DMZ is typically used to locate servers that need to be accessed from outside, like e-mail servers, Web and DNS.

Here is a Dual firewalls DMZ typical for enterprise web applications:



Typically, the DMZ is located between two firewalls and connects these.
The first firewall (also called the "front-end" firewall) must be configured to allow both traffic destined both to the DMZ as well as to the internal network. The second firewall (also called "back-end" firewall) allows only traffic from the DMZ to the internal network. The first firewall handles a much larger amount of traffic than the second firewall.

The application server and database are protected with this schema