Está en la página 1de 46

1.

INTRODUCCION ________________________________________________________ 3
1.1 Qu es JDBC? ____________________________________________________ 3
1.1.1 Qu hace J DBC? __________________________________________________ 4
1.1.2 J DBC es un API de bajo nivel y una base para APIs de alto nivel. ___________ 4
1.1.3 J DBC frente a ODBC y otros APIs ____________________________________ 5
1.1.4 Modelos en dos y tres pisos. __________________________________________ 6
1.1.5 SQL Conforme ____________________________________________________ 7
1.2 Productos JDBC. _____________________________________________________ 8
1.2.1 J avaSoft Framework ________________________________________________ 9
1.2.2 Tipos de drivers J DBC _____________________________________________ 10
2. CONEXIN ___________________________________________________________ 11
2.1 Vista Preliminar _____________________________________________________ 11
2.1.1 Apertura de una conexin ___________________________________________ 11
2.1.2 Uso general de URLs ______________________________________________ 11
2.1.3 J DBC y URLs ___________________________________________________ 12
2.1.4 El subprotocolo odbc _____________________________________________ 14
2.1.5 Registro de subprotocolos ___________________________________________ 14
2.1.6 Envio de Sentencias SQL ___________________________________________ 15
2.1.7 Transacciones ____________________________________________________ 16
2.1.8 Niveles de aislamiento de transacciones ________________________________ 17
3. LA CLASE DriverManager _______________________________________________ 18
3.1 Vista preliminar _____________________________________________________ 18
3.1.1 Mantenimiento de la lista de drivers disponibles. _________________________ 18
3.1.2 Establecer una conexin ____________________________________________ 19
4. LA CLASE Statement ____________________________________________________ 21
4.1 Vista Preliminar _____________________________________________________ 21
4.1.1 Creacin de objetos Statement _______________________________________ 21
4.1.2 Ejecucin de sentencias usando objetos Statement. _______________________ 22
4.1.3 Realizacin de Statement ___________________________________________ 23
4.1.4 Cerrar objetos Statement. ___________________________________________ 23
4.1.5 Sintaxis de Escape SQL en objetos Statement ___________________________ 23
4.1.6 Uso del mtodo execute ____________________________________________ 26
5. LA CLASE ResultSet ____________________________________________________ 29
5.1 Vista Preliminar _____________________________________________________ 29
5.1.1 Filas y Cursores___________________________________________________ 29
5.1.2 Columnas _______________________________________________________ 30
5.1.3 Tipos de datos y conversiones. _______________________________________ 31
5.1.4 Uso de Streams valores muy grandes de filas ____________________________ 32
5.1.5 Valores resultado NULL ____________________________________________ 34
5.1.6 Result sets opcionales o mltiples. ____________________________________ 34
2
6. LA CLASE PreparedStatement ____________________________________________ 35
6.1 Vista Preliminar _____________________________________________________ 35
6.1.1 Creacin de objetos PreparedStatement ________________________________ 35
6.1.2 Pasar parmetros IN _______________________________________________ 36
6.1.3 Conformidad de tipos de datos en parmetros IN _________________________ 37
6.1.4 Usar setObject ____________________________________________________ 37
6.1.5 Envo de J DBC NULL como un parmetro IN __________________________ 38
6.1.6 Envio de parmetros IN muy grandes. _________________________________ 38
7. LA CLASE CallableStatement______________________________________________ 39
7.1 Vista Preliminar _____________________________________________________ 39
7.1.1 Crear objetos CallableStatement ______________________________________ 40
7.1.2 Parmetros IN y OUT ______________________________________________ 40
7.1.3 Parmetros INOUT ________________________________________________ 41
7.1.4 Recuperar parmetros OUT despus de resultados _______________________ 42
7.1.5 Recuperar valores NULL en parmetros OUT ___________________________ 42
9. EJEMPLO DE CODIGO__________________________________________________ 43


3
JDBC.

1. INTRODUCCION

Java Database Connectivity (JDBC) es una interfase de acceso a bases de datos
estndar SQL que proporciona un acceso uniforme a una gran variedad de bases
de datos relacionales. JDBC tambin proporciona una base comn para la
construccin de herramientas y utilidades de alto nivel.

El paquete actual de JDK incluye JDBC y el puente JDBC-ODBC. Estos paquetes
son para su uso con JDK 1.0

Drivers JDBC

Para usar JDBC con un sistema gestor de base de datos en particular, es necesario
disponer del driver JDBC apropiado que haga de intermediario entre sta y JDBC.
Dependiendo de varios factores, este driver puede estar escrito en Java puro, o ser
una mezcla de Java y mtodos nativos JNI (Java Native Interface).


1.1 Qu es JDBC?


JDBC es el API para la ejecucin de sentencias SQL. (Como punto de inters JDBC
es una marca registrada y no un acrnimo, no obstante a menudo es conocido
como Java Database Connectivity). Consiste en un conjunto de clases e
interfases escritas en el lenguaje de programacin Java. JDBC suministra un API
estndar para los desarrolladores y hace posible escribir aplicaciones de base de
datos usando un API puro Java.

Usando JDBC es fcil enviar sentencias SQL virtualmente a cualquier sistema de
base de datos. En otras palabras, con el API JDBC, no es necesario escribir un
programa que acceda a una base de datos Sybase, otro para acceder a Oracle y
otro para acceder a Informix. Un nico programa escrito usando el API JDBC y el
programa ser capaz de enviar sentencias SQL a la base de datos apropiada. Y,
con una aplicacin escrita en el lenguaje de programacin Java, tampoco es
necesario escribir diferentes aplicaciones para ejecutar en diferentes plataformas.
La combinacin de Java y JDBC permite al programador escribir una sola vez y
ejecutarlo en cualquier entorno.

Java, siendo robusto, seguro, fcil de usar, fcil de entender, y descargable
automticamente desde la red, es un lenguaje base excelente para aplicaciones de
base de datos.
4
JDBC expande las posibilidades de Java. Por ejemplo, con Java y JDBC API, es
posible publicar una pgina web que contenga un applet que usa informacin
obtenida de una base de datos remota. O una empresa puede usar JDBC para
conectar a todos sus empleados (incluso si usan un conglomerado de mquinas
Windows, Macintosh y UNIX) a una base de datos interna va intranet. Con cada
vez ms y ms programadores desarrollando en lenguaje Java, la necesidad de
acceso fcil a base de datos desde Java contina creciendo.

1.1.1 Qu hace JDBC?

Simplemente JDBC hace posible estas tres cosas:

Establece una conexin con la base de datos.
Enva sentencias SQL
Procesa los resultados.

El siguiente fragmento de cdigo nos muestra un ejemplo bsico de estas tres
cosas:

Connect i on con = Dr i ver Manager . get Connect i on (
" j dbc: odbc: wombat " , " l ogi n" , " passwor d" ) ;
St at ement st mt = con. cr eat eSt at ement ( ) ;
Resul t Set r s = st mt . execut eQuer y( " SELECT a, b, c FROM Tabl e1" ) ;
whi l e ( r s. next ( ) ) {
i nt x = r s. get I nt ( " a" ) ;
St r i ng s = r s. get St r i ng( " b" ) ;
f l oat f = r s. get Fl oat ( " c" ) ;
}

1.1.2 JDBC es un API de bajo nivel y una base para APIs de alto nivel.
JDBC es una interfase de bajo nivel, lo que quiere decir que se usa para invocar o
llamar a comandos SQL directamente. En esta funcin trabaja muy bien y es ms
fcil de usar que otros APIs de conexin a bases de datos, pero est diseado de
forma que tambin sea la base sobre la cual construir interfaces y herramientas de
alto nivel. Una interfase de alto nivel es amigable, usa un API mas entendible o
ms conveniente que luego se traduce en la interfase de bajo nivel tal como JDBC.

5
1.1.3 JDBC frente a ODBC y otros APIs
En este punto, el ODBC de Microsoft (Open Database Connectvity), es
probablemente el API ms extendido para el acceso a bases de datos relacionales.
Ofrece la posibilidad de conectar a la mayora de las bases de datos en casi todas
las plataformas. Por qu no usar, entonces, ODBC, desde Java?.

La respuesta es que se puede usar ODBC desde Java, pero es preferible hacerlo
con la ayuda de JDBC mediante el puente JDBC-ODBC. La pregunta es ahora por
qu necesito JDBC?. Hay varias respuestas a estas preguntas:

1.- ODBC no es apropiado para su uso directo con Java porque usa una
interface C. Las llamadas desde Java a cdigo nativo C tienen un nmero de
inconvenientes en la seguridad, la implementacin, la robustez y en la
portabilidad automtica de las aplicaciones.

2.- Una traduccin literal del API C de ODBC en el API Java podra no ser
deseable. Por ejemplo, Java no tiene punteros, y ODBC hace un uso copioso
de ellos, incluyendo el notoriamente propenso a errores void * . Se puede
pensar en JDBC como un ODBC traducido a una interfase orientada a objeto
que es el natural para programadores Java.

3. ODBC es difcil de aprender. Mezcla caractersticas simples y avanzadas
juntas, y sus opciones son complejas para querys simples. JDBC por otro
lado, ha sido diseado para mantener las cosas sencillas mientras que permite
las caractersticas avanzadas cuando stas son necesarias.

4. Un API Java como JDBC es necesario en orden a permitir una solucin
Java pura. Cuando se usa ODBC, el gestor de drivers de ODBC y los drivers
deben instalarse manualmente en cada mquina cliente. Como el driver JDBC
esta completamente escrito en Java, el cdigo JDBC es automticamente
instalable, portable y seguro en todas las plataformas Java.

En resumen, el API JDBC es el interfase natural de Java para las abstracciones y
conceptos bsicos de SQL. JDBC retiene las caractersticas bsicas de diseo de
ODBC; de hecho, ambos interfaces estn basados en el X/Open SQL CLI (Call
Level Interface).

Ms recientemente Microsoft ha introducido nuevas API detrs de ODBC. RDO,
ADO y OLE DB. Estos diseos se mueven en la misma direccin que JDBC en
muchas maneras, puesto que se les da una orientacin a objeto basndose en
clases que se implementan sobre ODBC.
6
1.1.4 Modelos en dos y tres pisos.

El API JDBC soporta los modelos en dos y tres pisos de acceso a base de datos.

En el modelo de dos-pisos, un applet Java o una aplicacin habla directamente con
la base de datos. Esto requiere un driver JDBC que pueda comunicar con el gestor
de base de datos particular al que se pretende acceder. Las sentencias SQL de
usuario se envan a la base de datos, y el resultado de estas sentencias se envan
al usuario. La base de datos puede estar localizada en otra mquina a la que el
usuario se conecta mediante la red. Esta es una configuracin Cliente/Servidor en la
que la mquina del usuario es el cliente y la mquina que hospeda a la base de
datos es el servidor. La red puede ser una intranet, por ejemplo, que conecta a los
empleados dentro de la corporacin, o puede ser Internet.

En el modelo de tres-pisos, los comandos se envan a un piso intermedio de
servicios, que enva las sentencias SQL a la base de datos. La base de datos
procesa las sentencias SQL y devuelve los resultados a el piso intermedio, que a
su vez lo enva al usuario. Los directores de IS encuentran este modelo muy
atractivo por que el piso intermedio hace posible mantener el control sobre los
datos y los tipos de actualizaciones que pueden hacerse en los datos corporativos.
Otra ventaja es que el usuario puede emplear un API de alto nivel ms sencillo que
es traducido por el piso intermedio en las llamadas de bajo nivel apropiadas.
Finalmente en muchos casos la arquitectura de tres niveles puede proporcionar
ventajas de rendimiento.

Hasta ahora, este nivel intermedio ha sido escrito en lenguajes como C C++, que
ofrecen un rendimiento ms rpido. De cualquier modo, con la introduccin de
compiladores optimizadores que traducen el bytecode en cdigo mquina eficiente,
se est convirtiendo en prctico desarrollar este nivel intermedio en Java.
Aplicacion
Java
JDBC
DBMS
Protocolo propietario DBMS
Mquina cliente
Servidor de BD.
7
Esta es una gran ventaja al hacer posible aprovechar las caractersticas de
robustez, multiproceso y seguridad de Java.

1.1.5 SQL Conforme

SQL es el lenguaje estndar para el acceso a las bases de datos relacionales. Una
de las reas de dificultad es que aunque muchas DBMSs (Data Base Management
Systems) usan un formato estndar de SQL para la funcionalidad bsica, estos no
conforman la sintaxis ms recientemente definidas o semnticas para
funcionalidades ms avanzadas. Por ejemplo, no todas las bases de datos soportan
procedimientos almacenados o joins de salida, y aquellas que lo hacen no son
consistentes con otras. Es de esperar que la porcin de SQL que es
verdaderamente estndar se expandir para incluir ms y ms funcionalidad.
Entretanto, de cualquier modo, el API de JDBC debe soportar SQL tal como es.

Una forma en que el API JDBC trata este problema es permitir que cualquier
cadena de bsqueda se pase al driver subyacente del DBMS. Esto quiere decir que
una aplicacin es libre de usar la sentencia SQL tal como quiera, pero se corre el
riesgo de recibir un error en el DBMS. De hecho una consulta de una aplicacin
incluso no tiene por que ser SQL, o puede ser una derivacin especializada de SQL
Aplicacion
Java
DBMS
Mquina cliente
Servidor de BD.
Aplicacion
Servidora
(Java)
JDBC
llamadas HTTP, RML CORBA
Servidor (Lgica de negocio)
Protocolo propietario del DBMS
8
diseada para especificas DBMS (para consultas a imgenes o documentos por
ejemplo).

Una segunda forma en que JDBC trata este problema es proveer clusulas de
escape al estilo de ODBC , que se discutirn en el 4.1.5. Sintaxis de escape en
Sentencias Objetos.

La sintaxis de escape provee una sintaxis JDBC estndar para varias de las reas
ms comunes de divergencia SQL. Por ejemplo, ah escapes para literales de fecha
o procedimientos almacenados.

Para aplicaciones complejas, JDBC trata la conformidad SQL de una tercera
manera. Y es proveer informacin descriptiva sobre el DBMS por medio de la
interfase Dat abaseMet aDat a por la que las aplicaciones pueden adaptarse a los
requerimientos y posibilidades de cada DBMS:

Como el API JDBC se usar como base para el desarrollo de herramientas de
acceso y APIs de alto nivel , direccionar el problema de la conformidad a
cualquiera de estas. La designacin JDBC COMPLIANT se cre para situar un
nivel estndar de funcionalidad JDBC en la que los usuarios puedan confiar. En
orden a usar esta designacin, un driver debe soportar al menos el nivel de entrada
ANSI SQL-2 Entry Level. Los desarrolladores de drivers pueden cerciorarse que sus
drivers cumplan estas especificaciones mediante la suite de test disponible en el
API JDBC.

La designacin JDBC COMPLIANT indica que la implementacin JDBC de un
vendedor ha pasado los tests de conformidad suministrados por JavaSoft. Estas
pruebas de conformidad chequean la existencia de todas las clases y mtodos
definidos en el API JDBC, y chequean tanto como es posible que la funcionalidad
SQL Entry Level est disponible. Tales tests no son exhaustivos, por supuesto, y
JavaSoft no esta distribuyendo implementaciones de vendedores, pero esta
definicin de compliance tiene algn grado de seguridad en una implementacin
JDBC. Con la mayor aceptacin de JDBC por parte de vendedores de bases de
datos, de servicios de Internet y desarrolladores, JDBC se est convirtiendo en el
estndar de acceso a bases de datos.

1.2 Productos JDBC.

Existen una serie de productos basados en JDBC que ya han sido desarrollados.
Por supuesto la informacin de este apartado ser rpidamente obsoleta.

ht t p: / / j ava. sun. com/ pr oduct s/ j dbc

9
1.2.1 JavaSoft Framework

JavaSoft suministra tres componentes JDBC como parte del JDK

El gestor de drivers JDBC

La suite de testeo de drivers JDBC

El puente JDBC-ODBC

El gestor de drivers es la espina dorsal de la arquitectura JDBC. Actualmente es
bastante pequea y simple; su funcin principal es conectar las aplicaciones Java al
driver JDBC correcto y despus soltarlo.

La suite de testeo JDBXC suministra seguridad y confianza en los drivers JDBC que
se ejecutarn en el programa. Solo los drivers que pasan el test pueden ser
designados JDBC COMPLIANT.

El puente JDBC-ODBC permite a los drivers ODBC usarse como drivers JDBC. Fue
implementado como una forma de llegar rpidamente al fondo de JDBC y para
proveer de acceso a los DBMS menos populares si no existen drivers JDBC para
ellos.

10
1.2.2 Tipos de drivers JDBC

Los drivers que son susceptibles de clasificarse en una de estas cuatro categoras.

1.- puente JDBC-ODBC ms driver ODBC: El producto de JavaSoft suministra
acceso va drivers ODBC. Ntese que el cdigo binario ODBC, y en muchos casos
el cdigo cliente de base de datos, debe cargarse en cada mquina cliente que use
este driver. Como resultado, este tipo de driver es el ms apropiado en un red
corporativa donde las instalaciones clientes no son un problema mayor, o para una
aplicacin en el servidor escrito en Java en una arquitectura en tres-niveles.

2.- driver Java parcialmente Nativo. Este tipo de driver convierte llamadas JDBC en
llamadas del API cliente para Oracle, Sybase, Informix, DB2 y otros DBMS. Ntese
que como el driver puente, este estilo de driver requiere que cierto cdigo binario
sea cargado en cada mquina cliente.

3.- driver Java nativo JDBC-Net. Este driver traduce llamadas JDBC al protocolo de
red independiente del DBMS que despus es traducido en el protocolo DBMS por el
servidor. Este middleware en el servidor de red es capaz de conectar a los clientes
puros Java a muchas bases de datos diferentes. El protocolo especfico usado
depender del vendedor. En general esta es la alternativa ms flexible.

4.- driver puro Java y nativo-protocolo.. Este tipo de driver convierte llamadas JDBC
en el protocolo de la red usado por DBMS directamente. Esto permite llamadas
directas desde la mquina cliente al servidor DBMS y es la solucin ms prctica
para accesos en intranets. Dado que muchos de estos protocolos son propietarios,
los fabricantes de bases de datos sern los principales suministradores.

Esperamos que las alternativas 3 y 4 sean las formas preferidas de acceder a las
bases de datos desde JDBC. Las categoras 1 y 2 son soluciones interinas cuando
no estn disponibles drivers directos puros Java.

11
2. CONEXIN

2.1 Vista Preliminar

Un objeto Connection representa una conexin con una base de datos. Una
sesin de conexin incluye las sentencias SQL que se ejecutan y los resultados que
son devueltos despus de la conexin. Una nica aplicacin puede tener una o ms
conexiones con una nica base de datos, o puede tener varias conexiones con
varias bases de datos diferentes.

2.1.1 Apertura de una conexin

La forma estndar de establecer una conexin a la base de datos es mediante la
llamada al mtodo DriverManager.getConnection. Este mtodo toma una
cadena que contiene una URL. La clase Dr i ver Manager , referida como la capa
de gestin JDBC, intenta localizar un driver que pueda conectar con la base de
datos representada por la URL. La clase Dr i ver Manager mantiene una lista de
clases Dr i ver registradas y cuando se llama al mtodo get Connect i on, se
chequea con cada driver de la lista hasta que encuentra uno que pueda conectar
con la base de datos especificada en la URL. El mtodo connect de Dr i ver usa
esta URL para establecer la conexin.

Un usuario puede evitar la capa de gestin de JDBC y llamar a los mtodos de
Dr i ver directamente. Esto puede ser til en el caso raro que dos drivers puedan
conectar con la base de datos y el usuario quiera seleccionar uno explcitamente.
Normalmente, de cualquier modo, es mucho ms fcil dejar que la clase
Dr i ver Manager maneje la apertura de la conexin.

El siguiente cdigo muestra como ejemplo una conexin a la base de datos
localizada en la URL j dbc: odbc: wombat con un user ID de oboy y password
12j ava.

St r i ng ur l = " j dbc: odbc: wombat " ;
Connect i on con = Dr i ver Manager . get Connect i on( ur l , " oboy" , " 12J ava" ) ;

2.1.2 Uso general de URLs

Dado que URLs causan a menudo cierta confusin, daremos primero una breve
explicacin de URL en general y luego entraremos en una discusin sobre URLs de
JDBC.
12
Una URL (Uniform Resource Locator) da informacin para localizar un recurso en
Internet. Puede pensarse en ella como una direccin.
La primera parte de una URL especifica el protocolo usado para acceder a la
informacin y va siempre seguida por dos puntos. Algunos protocolos comunes son
f t p, que especifica file transfer protocol y ht t p que especifica hypertext transfer
protocol. Si el protocolo es f i l e indica que el recurso est en un sistema de
ficheros local mejor que en Internet : veamos unos ejemplos:

ftp:/ / j avasof t . com/ docs/ J DK- 1_api docs. zi p
http:/ / j ava. sun. com/ pr oduct s/ j dk/ Cur r ent Rel ease
file: / home/ har ol dw/ docs/ books/ t ut or i al / summar y. ht ml

El resto de la URL, todo despus de los dos puntos, da informacin sobre donde se
encuentra la fuente de los datos. Si el protocolo es file, el resto de la URL es el path
al fichero. Para los protocolos f t p y ht t p, el resto de la URL identifica el host y
puede opcionalmente dar un path ms especfico al sitio. Por ejemplo, el siguiente
es la URL para la home page de JavaSoft. Esta URL identifica solo al host:

ht t p: / / j ava. sun. com

2.1.3 JDBC y URLs

Una URL JDBC suministra una forma de identificar una base de datos para que el
driver apropiado pueda reconocerla y establecer la conexin con ella. Los
desarrolladores de drivers son los que determinan actualmente que JDBC URL
identifica su driver particular. Los usuarios no tienen por que preocuparse sobre
como se forma una URL JDBC; ellos simplemente usan la URL suministrada con el
driver que usan. El rol de JDBC es recomendar algunas convenciones a los
fabricantes de drivers para su uso.

Dado que los JDBC URL se usan con varios tipos de drivers, las convenciones son
necesariamente muy flexibles. Primero, permiten a diferentes drivers usar diferentes
esquemas para nombrar las bases de datos. EL subprotocolo odbc, por ejemplo,
permite que las URL contengan valores de atributos (pero no los requieren).

Segundo, las URLs JDBC permiten a los desarrolladores de drivers codificar toda la
informacin de la conexin dentro de ella. Esto hace posible, por ejemplo, para un
applet que quiera hablar con una base de datos dada el abrir la conexin sin
necesitar que el usuario realice ninguna tarea de administracin de sistemas.

Tercero, las URLs JDBC permiten un nivel de indireccin. Esto quiere decir que la
URL JDBC puede referirse a una base de datos lgica o un host lgico que se
traduce dinmicamente al nombre actual por el sistema de nombramiento de la red.
13
Esto permite a los administradores de sistemas evitar dar especificaciones de sus
hosts como parte del nombre JDBC. Hay una variedad de servicios de nomenclatura
de red diferentes (tales como DNS, NIS y DCE), y no hay restriccin acerca de cual
usar.
La sintaxis para las URLs JDBC que se muestra a continuacin tiene tres partes
separadas por dos puntos:

jdbc:<subprotocol>:<subname>

Las tres partes se descomponen como sigue:

1 jdbc el protocolo. El protocolo en una URL JDBC es siempre j dbc

2 - <subpr ot ocol >- el nombre del driver o el nombre del mecanismo de
conectividad con la base de datos, que puede estar soportado por uno o ms
drivers. Un ejemplo sobresaliente de un subprotocolo es odbc, que ha sido
reservado para URLs que especifican nombres de fuentes de datos estilo
ODBC. Por ejemplo para acceder a la base de datos a travs del puente
JDBC-ODBC, la URL a usar podra ser algo as como lo siguiente:

j dbc: odbc: f r ed

En este ejemplo, el subprotocolo es odbc y el subnombre fred es el
nombre de la fuente de datos ODBC local.

Si se quiere usar un servicio de nombre de la red (ya que el nombre de la
base de datos en la URL JDBC no tiene por que ser su nombre actal), el
servicio de nombre puede ser el subprotocolo. Por tanto, para el ejemplo,
podra tener una URL como :

j dbc: dcenami ng: account s- payabl e

En este ejemplo, la URL especifica que el servicio local DCE resolver el
nombre de la base de datos accounts-payable para poder conectar con la
base de datos real.

3 <subname> - una forma de identificar la base de datos. El subnombre puede
variar dependiendo del subprotocolo, y puede tener un subnombre con
cualquier sintaxis interna que el fabricante del driver haya escogido. El punto
de un subnombre es para dar informacin suficiente para localizar la base de
datos. En el ejemplo anterior fred es suficiente porque ODBC suministra la
informacin restante. Una base de datos en un servidor remoto requiere ms
informacin. Si la base de datos va a ser accesible a travs de Internet, por
ejemplo, la direccin de red debera incluirse en la URL JDBC como parte del
14
subnombre y debera seguir a la convencin estndar de nomenclatura de URL.

//hostname:port/subsubname

Suponiendo que dbnet es un protocolo para conectar a un host, la URL JDBC
debera parecerse a algo como:

j dbc: dbnet : / / wombat : 356/ f r ed

2.1.4 El subprotocolo odbc

El subprotocolo odbc es un caso especial. Ha sido reservado para URLs que
especifican el estilo ODBC de nombres de fuentes de datos y que tiene la
caracterstica de permitir especificar cualquier nmero de valores de atributos
despus del subnombre (el nombre de la fuente de datos) La sintaxis completa para
el protocolo odbc es:

j dbc: odbc: <dat a- sour ce- name>[ ; <at t r i but e- name>=<at t r i but e- val ue>] *

Todos los siguientes son nombres vlidos jdbc:odbc

j dbc: odbc: qeor 7
j dbc: odbc: wombat
j dbc: odbc: wombat ; CacheSi ze=20; Ext ensi onCase=LOWER
j dbc: odbc: qeor a; UI D=kgh; PWD=f ooey

2.1.5 Registro de subprotocolos

Un desarrollador de drivers puede reservar un nombre para usar como el
subprotocolo en una URL JDBC. Cuando la clase Dr i ver Manager presenta este
nombre a su lista de drivers registrados, el driver para el que este nombre est
reservado debera reconocerlo y establecer una conexin a la base de datos que lo
identifica. Por ejemplo odbc est reservado para el puente JDBC-ODBC. Si fuera,
por poner otro ejemplo, Miracle Corporation, y quisiera registrar miracle como el
subprotocolo para el driver JDBC que conecte a su DBMS Miracle no tiene que usar
sino ese nombre.

15
2.1.6 Envo de Sentencias SQL

Una vez que la conexin se haya establecido, se usa para pasar sentencias SQL a
la base de datos subyacente. JDBC no pone ninguna restriccin sobre los tipos de
sentencias que pueden enviarse: esto da un alto grado de flexibilidad, permitiendo el
uso de sentencias especficas de la base de datos o incluso sentencias no SQL. Se
requiere de cualquier modo, que el usuario sea responsable de asegurarse que la
base de datos subyacente sea capaz de procesar las sentencias SQL que le estn
siendo enviadas y soportar las consecuencias si no es as. Por ejemplo, una
aplicacin que intenta enviar una llamada a un procedimiento almacenado a una
DBMS que no soporta procedimientos almacenados no tendr xito y generar una
excepcin. JDBC requiere que un driver cumpla al menos ANSI SQL-2 Entry Level
para ser designado JDBC COMPLIANT. Esto significa que los usuarios pueden
contar al menos con este nivel de funcionalidad.

JDBC suministra tres clases para el envo de sentencias SQL y tres mtodos en la
interfaz Connect i on para crear instancias de estas tres clases. Estas clases y
mtodos son los siguientes:

1.- Statement creada por el mtodo cr eat eSt at ement . Un objeto
St at ement se usa para enviar sentencias SQL simples

2.- PreparedStatement creada por el mtodo pr epar eSt at ement - Un objeto
Pr epar edSt at ement se usa para sentencias SQL que toman uno o ms
parmetros como argumentos de entrada (parmetros IN). Pr epar edSt at ement
tiene un grupo de mtodos que fijan los valores de los parmetros IN, los cuales son
enviados a la base de datos cuando se procesa la sentencia SQL. Instancias de
Pr epar edSt at ement extienden St at ement y por tanto heredan los mtodos de
St at ement . Un objeto Pr epar edSt at ement es potencialmente ms eficiente que
un objeto St at ement porque este ha sido precompilado y almacenado para su uso
futuro.

3.- CallableStatement creado por el mtodo pr epar eCal l . Los objetos
Cal l abl eSt at ement se usan para ejecutar procedimientos almacenados SQL
un grupo de sentencias SQL que son llamados mediante un nombre, algo parecido
a una funcin - . Un objeto Cal l abl eSt at ement hereda mtodos para el manejo
de los parmetros IN de Pr epar edSt at ement , y aade mtodos para el manejo
de los parmetros OUT e INOUT.

La lista siguiente da una forma rpida de determinar que mtodo Connection es el
apropiado para crear los diferentes tipos de sentencias SQL.
16
El mtodo createStatement se usa para:

Sentencias SQL simples (sin parmetros).

El mtodo pr epar eSt at ement se usa para:

Sentencias SQL con uno ms parmetros IN
Sentencias SQL simples que se ejecutan frecuentemente

El mtodo pr epar eCal l se usa para:

Llamar a procedimientos almacenados.


2.1.7 Transacciones

Una transaccin consiste en una o ms sentencias que han sido ejecutadas,
completas y, o bien se ha hecho commit o bien roll-back. Cuando se llama al
mtodo commi t o r ol l back , la transaccin actal finaliza y comienza otra.

Una conexin nueva se abre por defecto en modo auto-commit, y esto significa que
cuando se completa se llama automticamente al mtodo commi t . En este caso,
cada sentencia es commitada individualmente, por tanto una transaccin se
compone de una nica sentencia. Si el modo auto-commit es desactivado, la
transaccin no terminar hasta que se llame al mtodo commi t o al mtodo
r ol l back explcitamente, por lo tanto incluir todas las sentencias que han sido
ejecutadas desde la ltima invocacin a uno de los mtodos commit o rollback. En
este segundo caso, todas las sentencias de la transaccin son commitadas o
deshechas en grupo.

El mtodo commit hace permanente cualquier cambio que una sentencia SQL
realiza en la base de datos, y libera cualquier bloqueo mantenido por la transaccin.
El mtodo rollback descarta estos cambios.

A veces un usuario no quiere que tenga efecto un determinado cambio a menos que
se efectu otro. Esto puede hacerse desactivando el modo auto-commit y
agrupando ambas actualizaciones en una transaccin. Si ambas actualizaciones
tienen xito se llama al mtodo commi t haciendo estos cambios permanentes, si
uno o los dos fallan, se llama al mtodo rollback, restaurando los valores existentes l
inicio de la transaccin. Muchos drivers JDBC soportan transacciones. De hecho, un
driver JDBC-compliant debe soportar transacciones. DatabaseMetaData suministra
informacin que describe el nivel de transaccin soportado por el DBMS.
17

2.1.8 Niveles de aislamiento de transacciones

Si un DBMS soporta el proceso de transacciones, tendr que manejar de alguna
forma los potenciales conflictos que puedan surgir cuando dos transacciones estn
operando sobre una base de datos concurrentemente. El usuario puede especificar
un nivel de aislamiento para indicar que nivel de precaucin debera ejercitar el
DBMS para la resolucin de estos conflictos. Por ejemplo, que ocurrir cuando una
transaccin cambia un valor y una segunda transaccin lee el valor antes de que el
cambio haya sido commitado o descartado?. Debera permitirse, dado que el
valor cambiado ledo por la segunda transaccin ser invalido si la primera
transaccin ha hecho rollback?. Un usuario JDBC puede instruir a la DBMS para
que un valor que ha sido ledo antes del commit (dirty reads) con el siguiente
cdigo donde con es el objeto de la actual conexin:

con. set Tr ansact i onI sol at i on( TRANSACTI ON_READ_UNCOMMI TTED) ;

El nivel de aislamiento ms alto, el que ms cuidado toma para evitar conflictos. La
interfase Connect i on define cinco niveles de aislamiento con el nivel ms bajo que
especifica que no soporte transacciones hasta el ms alto que especifica que
mientras una transaccin est abierta ninguna otra transaccin puede realizar
cambios en los datos ledos por esa transaccin. Normalmente, el nivel de
transaccin ms alto es el ms lento en la ejecucin de la aplicacin.(debido a que
se incrementan los bloqueos y se disminuye la concurrencia de los usuarios). El
desarrollador debe balancear la necesidad de rendimiento con la necesidad de la
consistencia de los datos al tomar la decisin del nivel de aislamiento a usar. Por
supuesto, el nivel de aislamiento que pueda soportarse depende de las
posibilidades de la base de datos subyacente.

Cuando se crea un nuevo objeto Connect i on, su nivel de aislamiento depende del
driver, pero normalmente por defecto es el de la DBMS subyacente. Un usuario
puede llamar al mtodo set I sol at i onLevel para cambiar el nivel de aislamiento
de la transaccin, y este nuevo nivel estar efectivo durante la sesin de conexin.
Para cambiar el nivel de aislamiento solo para una transaccin, es necesario fijar
este antes de la transaccin comience y volverlo a situar en su valor anterior una
vez que la transaccin haya terminado. No se recomienda cambiar el nivel de
aislamiento de transaccin en medio de una puesto que lanzar una llamada
inmediata al mtodo commi t , provocando que los cambios hasta ese punto se
hagan permanentes en la base de datos.
18
3. LA CLASE DriverManager

3.1 Vista preliminar

La clase Dr i ver Manager implementa la capa de gestin de JDBC, y trabaja como
intermediaria entre el usuario y los drivers. Guarda la lista de los drivers que estn
disponibles y establece la conexin entre la base de datos y el driver apropiado.
Adems la clase Dr i ver Manager se ocupa de cosas cmo gestionar los lmites de
tiempo de login en el driver y de la salida de los mensajes de traza y log.

Para aplicaciones simples, el nico mtodo en esta clase que necesita un
programador general para su uso directamente es
Dr i ver Manager . get Connect i on. Como su nombre indica, este mtodo
establece una conexin con la base de datos. JDBC permite al usuario llamar a los
mtodos de Dr i ver Manager get Dr i ver , get Dr i ver s y r egi st er Dr i ver as
como al mtodo de Dr i ver connect , pero en la mayora de los casos es preferible
dejar que la clase DriverManager gestione los detalles al establecer la conexin.

3.1.1 Mantenimiento de la lista de drivers disponibles.

La clase Dr i ver Manager mantiene una lista de clases disponibles que han sido
registrados mediante el mtodo Dr i ver Manager . r egi st er Dr i ver . Todas las
clases Dr i ver deben escribirse con una seccin esttica que cree una instancia de
la clase y luego la registre en la clase Dr i ver Manager cuando se cargue. Adems
el usuario normalmente no debera llamar a Dr i ver Manager . r egi st er Dr i ver
directamente; debera llamarse automticamente por el driver cuando est se
carga,. Una clase Dr i ver se carga, y por tanto se registra, de dos formas
diferentes:

1 Mediante una llamada al mtodo Class.forName. Este carga explcitamente la
clase driver. Dado que no depende de ningn setup externo, esta forma de
cargar drivers es la recomendada. El siguiente cdigo carga la clase
acme. db. Dr i ver :

Cl ass. f or Name( " acme. db. Dr i ver " ) ;

Si acme. db. Dr i ver se ha escrito para que al cargar produzca una instancia
y llame al mtodo Dr i ver Manager . r egi st er Dr i ver con esta instancia
como argumento (es lo que debera hacer), entonces este estar en la lista
de drivers disponibles para efectuar la conexin.
19

2 Mediante la adicin del driver a la propiedad jdbc.drivers de java.lang.System-
Esta es una lista de nombres de clases de drivers, separadas por dos puntos,
que es la que carga la clase DriverManager. Cuando la clase DriverManager
se inicializa, mira en la propiedad jdbc.drivers, y si el usuario ha introducido
uno o ms drivers, la clase DriverManager intenta cargarlos. El siguiente
cdigo ilutsra como un programador debera introducir estas tres clases en
~/ . hot j ava/ pr oper t i es

j dbc. dr i ver s=f oo. bah. Dr i ver : wombat . sql . Dr i ver : bad. t est . our Dr i ver ;

La primera llamada a el mtodo Dr i ver Manager har que estos drivers se carguen
automticamente.

Notese que en esta segunda manera de cargar los drivers es necesario una
preparacin del entorno que es persistente. Si existe alguna duda sobre esto es
preferible y ms seguro llamar al mtodo Cl ass. f or Name para cargar
explicitamente cada driver. Este es tambin el mtodo que se usa para traer un
driver particular puesto que una vez que la clase Dr i ver Manager ha sido
inicializada no chequear la lista de propiedades jdbc.drivers.

En ambos casos, es responsabilidad de la clase Dr i ver recin cargada registrarse
a si misma mediante una llamada a Dr i ver Manager . r egi st er Dr i ver . Como
se ha mencionado anteriormente, esto debera hacerse automticamente al cargar
la clase.

Por razones de seguridad, la capa de gestin de JDBC guardar traza de que
clases de cargadores provee cada driver. Entonces cuando la clase DriverManager
abre una conexin solo usar los drivers que vienen desde el sistema de ficheros
local o desde las mismas clases cargadoras como el cdigo que solicita la conexin.

3.1.2 Establecer una conexin

Una vez que la clase Driver ha sido cargada y registrada con la clase
DriverManager, se est en condiciones de establecer la conexin con la base de
datos. La solicitud de la conexin se realiza mediante una llamada al mtodo
DriverManager.getConnection, y DriverManager testea los drivers regsitrados para
ver si puede establecer la conexin.

A veces puede darse el caso de que ms de un driver JDBC pueda establecer la
conexin para una URL dada. Por ejemplo, cuando conectamos con una base de
datos remota, podra ser posible usar un driver puente JDBC-ODBC, o un driver
JDBC de protocolo genrico de red, o un driver suministrado por el vendedor.
20
En tales casos, el orden en que los driver son testeados es significante porque
Dr i ver Manager usar el primer driver que encuentre que pueda conectar con xito
a la base de datos.

Primero DriverManager intenta usar cada driver en el orden en que ha sido
registrado ( los drivers listados en la propiedad jdbc.drivers son siempre los
registrados primero). Saltar cualquier driver con cdigo untrusted, a menos que se
cargue desde el mismo cdigo fuente que el cdigo que intenta abrir la conexin.

Testea los drivers mediante la llamada al mtodo Dr i ver . connect cada uno por
turno, pasndole como argumento la URL que el usuario ha pasado originalmente al
mtodo Dr i ver Manager . get Connect i on. El primer driver que reconozca la
URL realiza la conexin.

Una primera ojeda puede parecer insuficiente, pero son necesarias solo unas pocas
llamadas a procedimientos y comparaciones de cadena por conexin puesto que no
es probable que haya docenas de drivers se carguen concurrentemente.

El siguiente cdigo es un ejemplo de todo lo necesario normalmente para establecer
una conexin con un driver puente JDBC-ODBC:

Cl ass. f or Name( " sun. j dbc. odbc. J dbcOdbcDr i ver " ) ; / / l oads t he dr i ver
St r i ng ur l = " j dbc: odbc: f r ed" ;
Dr i ver Manager . get Connect i on( ur l , " user I D" , " passwd" ) ;

21
4. LA CLASE Statement

4.1 Vista Preliminar

Un objeto St at ement se usa para enviar sentencias SQL a la base de datos.
Actualmente hay tres tipos de objetos St at ement , todos los cuales actan como
contenedores para la ejecucin de sentencias en una conexin dada: St at ement ,
Pr epar edSt at ement que hereda de St at ement y Cal l abl eSt at ement que
hereda de Pr epar edSt at ement . Estas estn especializadas para enviar tipos
particulares de sentencias SQL, Un objeto St at ement se usa para ejecutar una
sentencia SQL simple sin parmetros. Un objeto Pr epar edSt at ement se usa para
ejecutar sentencias SQL precompiladas con o sin parmetros IN; y un objeto
Cal l abl eSt at ement se usa para ejecutar un procedimieno de base de datos
almacenado.

La interfase St at ement suminstra mtodos bsicos para ejecutar sentencias y
devolver resultados. La interfase Pr epar edSt at ement aade mtodos para
trabajat con los parmetros IN; y la interfase Cal l abl eSt at ement aade mtodos
para trabajar con parameters OUT.

4.1.1 Creacin de objetos Statement

Una vez establecida la conexin con una base de datos particular, esta conexin
puede usarse para enviar sentencias SQL. Un objeto St at ement se crea mediante
el mtodo de Connect i on cr eat eSt at ement , como podemos ver en el siguiente
fragmento de cdigo.

Connect i on con = Dr i ver Manager . get Connect i on( ur l , " sunny" , " " ) ;
St at ement st mt = con. cr eat eSt at ement ( ) ;

La sentencia SQL que ser enviada a la base de datos es alimentada como un
argumento a uno de los mtodos de ejecucin del objeto St at ement . Por ejemplo:

Resul t Set r s = st mt . execut eQuer y( " SELECT a, b, c FROM Tabl e2" ) ;

22
4.1.2 Ejecucin de sentencias usando objetos Statement.

La interfase St at ement nos suministra tres mtodos diferentes para ejecutar
sentencias SQL, execut eQuer y, execut eUpdat e y execut e. El mtodo a usar
esta determinado por el producto de la sentencia SQL

El mtodo execut eQuer y esta diseado para sentencias que producen como
resultado un nico result set tal como las sentencias SELECT.
El mtodo execut eUpdat e se usa para ejecutar sentencias I NSERT, UPDATE
DELETE as como sentencias SQL DDL (Data Definition Language) como CREATE
TABLE o DROP TABLE. El efecto de una sentencia I NSERT, UPDATE o DELETE es
una modificacin de una o ms columnas en cero o ms filas de una tabla. El valor
devuelto de execut eUpdat e es un entero que indica el nmero de filas que han
sido afectadas (referido como update count). Para sentencias tales como CREATE
TABLE o DROP TABLE, que no operan sobre filas, le valor devuelto por
execut eUpdat e es siempre cero.

El mtodo execut e se usa para ejecutar sentencias que devuelven ms de un
result set, ms que un update count o una combinacin de ambos. Como es esta
una caracterstica avanzada que muchos programadores no necesitaran nunca se
ver en su propia seccin.

Todos los mtodos que ejecutan sentencias cierran los objetos Resul t set abiertos
como resultado de las llamadas a St at ement . Esto quiere decir que es necesario
completar el proceso con el actual objeto Resul set antes de reejecutar una
sentencia St at ement .

Debe notarse que la interfase Pr epar edSt at ement , que hereda los mtodos de la
interfase St at ement , tiene sus propias versiones de los mtodos execut eQuer y,
execut eUpdat e y execut e. Los objetos Statement en si mismos no contienen
una sentencia SQL, por tanto debe suministrarse como un argumento a los mtodos
Statement.execut e. Los objetos Pr epar edSt at ement no suministran una
sentencia SQL como argumento a estos mtodos puesto que ya tienen la sentencia
precompilada. Los objetos Cal l abl eSt at ement heredan las formas de estos
mtodos de Pr epar edSt at ement . Usar un parametro de query con las versiones
de los mtodos de Pr epar edSt at ement o Cal l abl eSt at ement produciri una
SQLExcept i on,.

23
4.1.3 Realizacin de Statement
Cuando una conexin est en modo auto-commit, las sentencias ejecutadas son
comitadas o rechazadas cuando se completan. Un sentencia se considera
completa cuando ha sido ejecutada y se han devuelto todos los resultados. Pare el
mtodo execut eQuer y, que devuelve un nico result set, la sentencia se completa
cuando todas las filas del objeto Resul t Set se han devuelto. Para el mtodo
execut eUpdat e, un sentencia se completa cuando se ejecuta. En los raros casos
en que se llama al mtodo execut e, de cualquier modo, no se completa hasta que
los result sets o update counts que se generan han sido devueltos.

Algunos DBMS tratan cada sentencia en un procedimiento almacenado como
sentencias separadas. Otros tratan el procedimiento entero como una sentencia
compuesta. Esta diferencia se convierte en importante cuando est activo el modo
auto-commit porque afecta cuando se llama al mtodo commit. En el primer caso,
cada sentencia individual es commitada. En el segundo, se commiten todas juntas.

4.1.4 Cerrar objetos Statement.

Los objetos St at ement se cerrarn automticamente por el colector de basura de
Java (garbage collector). No obstante se recomienda como una buena prctica de
programacin que se cierren explicitamente cuando no sean ya necesarios. Esto
libera recursos DBMS inmediatamente y ayuda a evitar potenciales problemas de
memoria.

4.1.5 Sintaxis de Escape SQL en objetos Statement

Los objetos Statement pueden contener sentencias SQL que usen sintaxis de
escape SQL. La sintaxis de escape seala al driver que el cdigo que lleva debe ser
tratado diferentemente. El driver buscar por cualquier sintaxis de escape y lo
traducir en cdigo que entiende la base de datos en particular. Esto hace que la
sintaxis de escape sea independiente de la DBMS y permite al programador usar
caractersticas que de otro modo no estaran disponibles.

Una clausula de escape se enmarca entre llaves y tiene una palabra clave:

{keywor d . . . par amet er s . . . }

24
La palabra clave (keyword) indica el tipo de clausula de escape, segn se muestra:

escape para caracteres LIKE

Los caracteres % y _ trabajan como wildcards en la clausula SQL LIKE
(% significa cero o ms caracteres y _ significa exactamente un carcter.
En orden a interpretarlos literalmente, pueden estar precedidos por un
backslash (\), que es un carcter de escape especial en cadenas. Se puede
especificar un carcter que se use como carcter de escape por la inclusin
de la sintaxis siguiente al final de la consulta.

{escape ' escape- char act er ' }

Por ejemplo, la siguiente query, usando backslash como caracter de escape,
encuentra nombres de identificador que comiencen con _.

st mt . execut eQuer y( " SELECT name FROM I dent i f i er s
WHERE I d LI KE `\ _%' {escape `\ ' };


f n para funciones escalares

Casi todas las DBMS tienen funciones numricas, de cadena, de fecha y
conversin sobre valores escalares. Una de estas funciones puede usarse
colocndola en la sintaxis de escape con la clave f n seguida del nombre de
la funcin deseada y sus argumentos. Por ejemplo, para llamar a la funcin
concat con dos argumentos que sern concatenados:

{f n concat ( " Hot " , " J ava" ) };

El nombre del usuario actual de la base de datos puede obtenerse mediante:

{f n user ( ) };

Las funciones escalares pueden estar soportadas por diferentes DBMS con
ligeras diferencias de sintaxis, y pueden no estar disponibles en todos los
drivers. Varios mtodos de Dat abaseMet aDat a nos listarn las funciones
que estn soportadas. Por ejemplo, el mtodo getNumericFunctions devuelve
una lista de los nombres de las funciones numricas separadas por comas, el
mtodo getStringFunction nos devuelve los nombres de las funciones de
cadena, y as varas ms.

EL driver o bien mapear la llamada a la funcin escapada en su propia
sintaxis o implementar la funcin el mismo.
25

d, t y t s para literales de fecha y tiempo

Las DBMS difieren en la sintaxis que usan para los literales de fecha, tiempo
y timestamp. JDBC soporta un formato estndar ISO para estos literales y
usa una clausula de escape que el driver debe traducir a la representacin
del DBMS.

Por ejemplo, una fecha se especifica en SQL JDBC mediante la sintaxis:

{d `yyyy- mm- dd' }

En esta sintaxis, yyyy es el ao, mmes el mes y dd es el dia. El driver
reemplazar la clausula de escape por la representacin propia equivalente
de la DBMS. Por ejemplo, el driver reemplazara {d 1999- 02- 28} por 28-
FEB- 99 si este es el formato apropiado para la base subyacente.

Hay clausulas de escape anlogas para TI ME y TI MESTAMP

{t `hh: mm: ss' }
{t s `yyyy- mm- dd hh: mm: ss. f . . . ' }
La parte fraccional de los segundos ( . f . . . ) del TI MESTAMP puede
omitirse.

cal l ? = cal l para procedimientos almacenados

Si una database soporta procedimientos almacenados, estos pueden ser
invocados desde JDBC mediante:

{call procedure_name[(?, ?, . . .)]}

o, cuando el procedimiento devuelve como resultado un parmetro

{? = cal l pr ocedur e_name[ ( ?, ?, . . . ) ] }

Los corchetes indican que el material encerrado en ellos es opcional. Estos
no forman parte de la sintaxis.

Los argumentos de entrada pueden ser bien literales, bien parmetros. Ver la
seccin 7 CallableStatement de esta gua.

Se puede llamar al mtodo
Dat abaseMet aDat a. suppor t sSt or edPr ocedur es para ver si la base de
datos soporta procedimientos almacenados.
26

oj para joins de salida

La sintaxis para un outer join es:

{oj out er - j oi n}

donde outer-join es de la forma:

t abl e LEFT OUTER J OI N {t abl e | out er - j oi n} ON sear ch- condi t i on
Las Outer joins son una caracterstica avanzada, y solo puede chequearse la
gramtica SQL mediente una explicacin de ella. JDBC provee tres mtodos
de DatabaseMetaData para determinar que tipos de outer joins soporta un
driver: suppor t sOut er J oi ns, suppor t sFul l Out er J oi ns, y
suppor t sLi mi t edOut er J oi ns.
El mtodo St at ement . set EscapePr ocessi ng activa o desactiva el
procesamiento de escape. Por defecto la caracterstica se encuentra activada. Un
programador debera desactivar esta caracterstica en tiempo de ejecucin cuando
el rendimiento ha de ser mximo, pero normalmente debe estar activado. Debera
notarse que set EscapePr ocesi ng no trabaja con objetos Pr epar edSt at ement
por que la sentencia ya est preparada para enviar a la base de datos antes de
poder ser llamada.
4.1.6 Uso del mtodo execute

El mtodo execute debera usarse solamente cuando es posible que una sentencia
nos devuelva ms de un objeto Resul t set ., mas de un update count o una
combinacin de ambos. Estas mltiples posibilidades para resultados, aunque raras,
son posibles cuando se ejecutan ciertos procedimientos almacenados o por la
ejecucin dinmica de una string SQL desconocida (esto es, desconocida para el
programador de la aplicacin en tiempo de compilacin). Por ejemplo, una usuario
podra ejecutar un procedimiento almacenado (usando una objeto
Cal l abl eSt at ement y este procedimiento podra ejecutar una actualizacin,
despus una select, luego una actualizacin, despus una select y as.
Normalmente, alguien que usa un procedimiento almacenado sabr que se le va a
devolver.

Porque el mtodo execute maneja los casos que se salen de lo ordinario, no
sorprende que los resultados devueltos requieren algun manejo especial. Por
ejemplo, supongamos que se sabe que el procedimiento devuelve dos result sets.
27
Despus de usar el mtodo execut e para ejecutar el procedimiento, se debe llamar
al mtodo get Resul t Set para conseguir el primer result set y despus los
mtodos apropiados get XXX para recuperar los valores de l. Para conseguir el
segundo result set, se necesita llamar al mtodo get Mor eResul t s y y despues a
get Resul t Set de nuevo. Si se sabe que el procedimiento devuelve dos upadte
counts, se llama primero al mtodo get Updat eCount , seguido de
get Mor eResul t s y de nuevo get Updat eCount .

Aquellos casos en los que no se conoce que devolver se nos presenta una
situacin ms compleja. El mtodo execute devuelve t r ue si el resultado es un
objeto Resul t Set y f al se si es un i nt Java. Si devuelve un i nt , esto quiere
decir que el resultado o bien es un update count o que la sentencia que ha
ejecutado es un comando DDL. Lo primero que hay que hacer despus de llamar
execute es llmar o bien a get Resul t Set o get Updat eCount . Al mtodo
get Resul t Set se le llama para conseguir el primero de los dos o ms objetos
Resul t Set y al mtodo get Updat eCount para conseguir el primero de dos o ms
update counts.

Cuando el resultado de una sentencia SQL no es un result set, el mtodo
get Resul t Set devolver nul l . Esto quiere decir que el resultado es un update
count o que no hay ms resultados. La nica manera de encontrar que significa el
valor nul l en este caso es llamar al mtodo get Updat eCount , que devolver un
entero. Este entero ser el nmero de filas afectadas por la sentencia ejecutada o
1 para indicar o bien que el resultado es un result set o bien que no hay ms
resultados. Si el mtodo get Resul t Set ya ha devuelto null, el resultado no puede
ser un objeto Resul t Set , por lo que el valor devuelto de 1 tiene que ser que no
hay ms resultados. En otras palabras, no hay ms resultados cuando lo siguiente
es cierto:

( ( st mt . get Resul t Set ( ) == nul l ) && ( st mt . get Updat eCount ( ) == - 1) )

Si se ha llamado al mtodo get Resul t Set y se ha procesado el objeto
Resul t Set devuelto, es necesario llamar al mtodo get Mor eResul t s para ver si
hay ms result sets o update counts.. Si get Mor eResul t s devuelve true, entonces
es necesario llamar de nuevo a get Resul t Set para recuperar el siguiente result
set. Como ya se ha indicado anteriormente, si get Resul t set devuelve nul l hay
que llamar a Get Updat eCount para buscar que significa ese nul l si un update
count o que no hay ms resultados.

Cuando getMoreResults devuelve false quiere decir que la sentencia SQL ha
devuelto un update count o que no hay ms resultados. Por tanto es necesario
llamar al mtodo getUpdateCount para encontrar cual es el caso. En esta situacin,
no habr ms resultados cuando lo siguiente es cierto:
28
((stmt.getMoreResults() ==false) && (stmt.getUpdateCount() ==-1))

El siguiente cdigo muestra una forma de asegurarse que se ha accedido a todos
los result sets y update counts de una llamada al mtodo execute:

st mt . execut e( quer ySt r i ngWi t hUnknownResul t s) ;
whi l e ( t r ue) {
i nt r owCount = st mt . get Updat eCount ( ) ;
i f ( r owCount > 0) { / / t hi s i s an updat e count
Syst em. out . pr i nt l n( " Rows changed = " + count ) ;
st mt . get Mor eResul t s( ) ;
cont i nue;
}
i f ( r owCount == 0) { / / DDL command or 0 updat es
Syst em. out . pr i nt l n( " No r ows changed or st at ement was DDL
command" ) ;
st mt . get Mor eResul t s( ) ;
cont i nue;
}

/ / i f we have got t en t hi s f ar , we have ei t her a r esul t set
/ / or no mor e r esul t s

Resul t Set r s = st mt . get Resul t Set ;
i f ( r s ! = nul l ) {
. . . / / use met adat a t o get i nf o about r esul t set col umns
whi l e ( r s. next ( ) ) {
. . . / / pr ocess r esul t s
st mt . get Mor eResul t s( ) ;
cont i nue;
}
br eak; / / t her e ar e no mor e r esul t s

29
5. LA CLASE ResultSet

5.1 Vista Preliminar

Un ResultSet contiene todas las filas que satisfacen las condiciones de una
sentencia SQL y proporciona el acceso a los datos de estas filas mediante un
conjunto de mtodos get que permiten el acceso a las diferentes columnas de la
filas. El mtodo ResultSet.next se usa para moverse a la siguiente fila del result set,
convirtiendo a sta en la fila actal.

El formato general de un result set es una tabla con cabeceras de columna y los
valores correspondientes devueltos por la query. Por ejemplo, si la query es
SELECT a, b, c FROM Tabl e1, el resultado tendr una forma semejante a :

a b c
- - - - - - - - - - - - - - - - - - - - - - - - -
12345 Cuper t i no CA
83472 Redmond WA
83492 Bost on MA

El siguiente fragmento de cdigo es un ejemplo de la ejecucin de una sentencia
SQL que devolver una coleccin de filas, con la columna 1 como un i nt , la
columna 2 como una St r i ng y la columna 3 como un array de bytes:

j ava. sql . St at ement st mt = conn. cr eat eSt at ement ( ) ;
Resul t Set r = st mt . execut eQuer y( " SELECT a, b, c FROM Tabl e1" ) ;
whi l e ( r . next ( ) )
{
/ / pr i nt t he val ues f or t he cur r ent r ow.
i nt i = r . get I nt ( " a" ) ;
St r i ng s = r . get St r i ng( " b" ) ;
f l oat f = r . get Fl oat ( " c" ) ;
Syst em. out . pr i nt l n( " ROW= " + i + " " + s + " " + f ) ;
}

5.1.1 Filas y Cursores

Un Resul t Set mantiene un cursor que apunta a la fila actal de datos. El cursor se
mueve una fila hacia abajo cada vez que se llama al mtodo next . Incialmente se
sita antes de la primera fila, por lo que hay que llamar al mtodo next para situarlo
en la primera fila conviertiendola en la fila actal. Las filas de Resul t Set se
recuperan en secuencia desde la fila ms alta a la ms baja.

Un cursor se mantiene vlido hasta que el objeto Resultset o su objeto padre
Statement se cierra.
30
En SQL, el cursor resultado para una tabla tiene nombre. Si una base de datos
permite upadtes posicionados o deletes posicionados, el nombre del cursor es
necesario y debe ser proporcionado como un parmetro del comando update o
delete. El nombre del cursor puede obtenerse mediante una llamada al mtodo
get Cur sor Name.

No todas las bases de datos soportan updates o deletes posicionados. Los mtodos
Dat abaseMet aDat a. suppor t sPosi t i onedDel et e y
Dat abaseMet aDat a. suppor t sPosi t i onedUpdat e nos permiten descubrir si
estas operaciones estn soportadas en una conexin dada. Cuando lo estn, el
driver o la DBMS deben asegurarse que las filas seleccionadas estn
apropiadamente bloquedas y por tanto que estas operaciones no provoquen
actualizaciones anomalas ni otros problemas de concurrencia.

5.1.2 Columnas

Los mtodos getXXX suministran los medios para recuperar los valores de las
columnas de la fila actal. Dentro de cada fila, los valores de las columnas pueden
recuperarse en cualquier orden, pero para asegurar la mxima portabilidad,
deberan extraerse las columnas de izquierda a derecha y leer los valores de las
columnas una nica vez.

Puede usarse o bien el nombre de la columna o el nmero de columna para
referirse a esta. Por ejemplo: si la columna segunda de un objeto Recor dSet rs se
denomina t i t l e y almacena valores de cadena, cualquiera de los dos ejemplos
siguientes nos devolver el valor almacenado en la columna.

St r i ng s = r s. get St r i ng( " t i t l e" ) ;
St r i ng s = r s. get St r i ng( 2) ;

Ntese que las columnas se numeran de izquierda a derecha comenzando con la
columna 1. Adems los nombres usados como input en los mtodos get XXX son
insensibles a las maysculas.

La opcin de usar el nombre de columna fue provista para que el usuario que
especifica nombres de columnas en una query pueda usar esos nombres como
argumentos de los mtodos get XXX. Si, por otro lado, la sentencia sel ect no
especifica nombres de columnas (tal como en sel ect * f r omt abl e1 o en
casos donde una columna es derivada), deben usarse los nmeros de columna. En
estas situaciones , no hay forma de que el usuario sepa con seguridad cuales son
los nombres de las columnas.
31

En algunos casos, es posible para una query SQL devolver un result set con ms de
una columna con el mismo nombre. Si se usa el nombre de columna como
argumento en un mtodo get XXX, ste devolver el valor de la primera columna
que coincida con el nombre. Por eso, si hay mltiples columnas con el mismo
nombre, se necesita usar un ndice de columna para asegurarse que se recupera el
valor de la columna correcta. Esto puede ser ligeramente ms eficiente que usar los
nmeros de columna.

Informacin acerca de las columnas en un Resul t Set es accesible mediante el
mtodo Resul t Set . get Met aDat a. El objeto Resul t Set Met aDat a devuelto nos
da el numero, tipo y propiedades de las columnas de los objetos Resul t Set .

Si se conoce el nombre de una columna, pero no su indice, puede usarse el mtodo
f i ndCol umn para encontrar el nmero de columna.

5.1.3 Tipos de datos y conversiones.

Para los mtodos getXXX, el driver JDBC intenta convertir los datos subyacentes a
tipos de datos Java . Por ejemplo, si el mtodo getXXX es getString y los tipos de
datos de la base de datos en la base subyacente es VARCHAR, el driver JDBC
convertir VARCHAR en String de Java. El valor devuelto por getString ser un
objeto Java de tipo String.

La siguiente tabla muestra que tipos JDBC est permitido devolver para un mtodo
getXXX y que tipos JDBC (tipos genricos de SQL) se recomiendan para
recuperarlos. Una x indica un mtodo getXXX legal para un tipo de dato particular.
Por ejemplo, cualquier mtodo getXXX excepto getBytes o getBinaryStream puede
usarse para recuperar valores de tipo LONGVARCHAR, pero se recomienda usar
getAsciiStream o getUnicodeStream, dependiendo de que tipo de dato se devuelve.
El mtodo getObject devolver cualquier tipo de dato como un Object Java y es util
cuando los tipos de datos de la DBMS subyacente son abstractos especficos de
sta o cuando una aplicacin genrica necesita aceptar cualquier tipo de datos.

El uso de los mtodos ResultSet.getXXX recuperan tipos de datos comunes JDBC

Una x indica que el mtodo getXXX puede legalmente usarse para recuperar el
tipo JDBC dado.

Una X indica que el mtodo getXXX es el recomendado para recuperar el tipo de
dato dado.
32
5.1.4 Uso de Streams valores muy grandes de filas

ResultSet hace posible el recuperar datos arbitrariamente grandes de tipo
LONGVARBINARY o LONGVARCHAR. Los mtodos getBytes y getString
devuelven valores grandes (hasta los lmites impuestos por el valor devuelto por
Statement.getMaxFieldSize).



T
I
N
Y
I
N
T
S
M
A
L
L
I
N
T
I
N
T
E
G
E
R
B
I
G

N
T
R
E
A
L
F
L
O
A
T
D
O
U
B
L
E
D
E
C
I
M
A
L
N
U
M
E
R
I
C
B
I
T
C
H
A
R
V
A
R
C
H
A
R
L
O
N
G
V
A
R
C
H
A
R
B
I
N
A
R
Y
V
A
R
B
I
N
A
R
Y
L
O
N
G
V
A
R
B
I
N
A
R
Y
D
A
T
E
T
I
M
E
T
I
M
E
S
T
A
M
P
getByte X x x x x x x x x x x x x
getShort x X x x x x x x x x x x x
getInt x x X x x x x x x x x x x
getLong x x x X x x x x x x x x x
getFloat x x x x X x x x x x x x x
getDouble x x x x x X X x x x x x x
getBigDecimal x x x x x x x X X x x x x
getBoolean x x x x x x x x x X x x x
getString x x x x x x x x x x X X x x x x x x x
getBytes X X x
getDate x x x X x
getTime x x x X x
getTimestamp x x x x X
getAsciiStream x x X x x x
getUnicodeStream x x X x x x
getBinaryStream x x X
getObject x x x x x x x x x x x x x x x x x x x
33
De todos modos, puede ser conveniente recuperar datos muy grandes en pedazos
de tamao fijo. Esto se hace mediante la clase Resul t Set que devuelve streams
java.io.Input desde los cuales los datos pueden ser leidos en pedazos. Ntese que
estas corrientes deben ser accedidas inmediatamente porque se cierran
automticamente con la llamada al siguiente mtodo get XXX de Resul t Set . (Este
comportamiento est impuesto por las restricciones de implementacin de acceso a
grandes blob).

El API JDBC tiene tres mtodos diferentes para recuperar streams, cada uno con un
valor diferente de retorno.

get Bi nar ySt r eamdevuelve una corriente que simplemente suminiistra
bytes en bruto desde la base de datos sin ninguna conversin.

get Asci i St r eamdevuelve una corriente con caracteres ASCII

get Uni codeSt r eamdevuelve una corriente con caracteres Unicode
1
de 2
bytes.

Notar que esto difiere de las corrientes Java que devuelven bytes sn tipo y pueden
(por ejemplo) usarse para ambos caracteres ASCII y Unicode.

A continuacin veamos un ejemplo del uso de getAsciiStream:

j ava. sql . St at ement st mt = con. cr eat eSt at ement ( ) ;
Resul t Set r = st mt . execut eQuer y( " SELECT x FROM Tabl e2" ) ;
/ / Now r et r i eve t he col umn 1 r esul t s i n 4 K chunks:
byt e buf f = new byt e[ 4096] ;
whi l e ( r . next ( ) ) {
J ava. i o. I nput St r eamf i n = r . get Asci i St r eam( 1) ;
f or ( ; ; ) {
i nt si ze = f i n. r ead( buf f ) ;
i f ( si ze == - 1) { / / at end of st r eam
br eak;
}
/ / Send t he newl y- f i l l ed buf f er t o some ASCI I out put st r eam:

1
Unicode
Unicode es un esquema de codificacin de caracteres que utiliza 2 bytes por cada carcter. ISO
(International Standards Organization) define un nmero dentro del intervalo 0 a 65.535 (2
16
1) por
cada carcter y smbolo de cada idioma (ms algunos espacios vacos para futuras ampliaciones).
En todas las versiones de 32 bits de Windows, el Modelo de objetos componentes (COM), que es la
base de las tecnologas OLE y ActiveX, utiliza Unicode. Unicode es totalmente compatible con
Windows NT. Aunque Unicode y DBCS tienen caracteres de doble byte, los esquemas de
codificacin son completamente diferentes.

34

out put . wr i t e( buf f , 0, si ze) ;
}
}

5.1.5 Valores resultado NULL

Para determinar si un valor resultado dado es JDBC NULL, primero debe intentarse
leer la columna y usar el mtodo Resul t Set . wasNul l para descubrir si el valor
devuelto es JDBC NULL

Cuando se ha leido un JDBC NULL usando uno de los mtodos
Resul t Set . get XXX, el mtodo wasNul l devuelve algo de lo siguiente:

Un valor null de Java para aquellos mtodos getXXX que devuelven objetos
Java (tales como get St r i ng, get Bi gDeci mal , get Byt es, get Dat e,
get Ti me, get Ti mest amp, get Asci i St r eam, get Uni codeSt r eam,
get Bi nar ySt r eam, get Obj ect ).

Un valor cero para get Byt e, get Shor t , get I nt , get Long,
get Fl oat y get Doubl e.

Un valor false para get Bool ean.

5.1.6 Result sets opcionales o mltiples.
Normalmente cuando se ejecuta una sentencia SQL o bien se usa excut eQuer y
(que devuelve un nico Resul t Set ) o bien execut eUpdat e (que puede usarse
para cualquier tipo de sentencia de modificacin de la base de datos y que devuelve
un contador de las filas que han sido afectadas. De cualquier modo, bajo ciertas
circunstancias una aplicacin puede no saber si una sentencia devolver un result
set hasta que sta no haya sido ejecutada. Adems, ciertos procedimientos
almacenados pueden devolver varios result sets y/o update counts.

Para acomodarse a estas situaciones, JDBC provee de un mecanismo por el cual
una aplicacin puede ejecutar una sentencia y luego procesar una coleccin
arbitraria de result sets y update counts. Este mecanismo se basa en una primera
llamada a un mtodo general execut e y luego llamar a otros tres mtodos
get Resul t Set , get Updat eCount y get Mor eResul t s. Estos mtodos permiten
a una aplicacin explorar los resultados de las sentencias y determinar si dan como
resultado un result set o un update count.
35
No se necesita hacer nada para cerrar un ResultSet. Se cierra automticamente
cuando por la St at ement que la crea cuando se cierra esta, y se reutiliza cuando
cuando se recupera el prximo resultado de una secuencia de mltiples resultados.

6. LA CLASE PreparedStatement

6.1 Vista Preliminar

La interfase PreparedStatement hereda de Statement y difiere de esta en dos
maneras.

Las instancias de Pr epar edSt at ement contienen una sentencia SQL que
ya ha sido compilada. Esto es lo que hace que se le llame preparada.

La sentencia SQL contenida en un objeto Pr epar edSt at ement pueden
tener uno o ms parmetros I N. Un parmetro I N es aquel cuyo valor no se
especifica en la sentencia SQL cuando se crea. En vez de ello la sentencia
tiene un interrogante (?) como un encaje para cada parmetro I N. Debe
suministrarse un valor para cada interrogante mediante el mtodo apropiado
set XXX antes de ejecutar la sentencia.

Como los objetos Pr epar edSt at ement estn precompilados, su ejecucin es ms
rpida que los objetos St at ement . Consecuentemente, una sentencia SQL que se
ejecute muchas veces a menudo se crea como Pr epar edSt at ement para
incrementar su eficacia.

Siendo una subclase de St at ement , Pr epar edSt at ement hereda toda la
funcionalidad de St at ement . Adems , se aade un set completo de mtodos
necesarios para fijar los valores que van a ser enviados a la base de datos en el
lugar de los encajes para los parmetros IN. Tambin se modifican los tres
mtodos execut e, execut eQuer y y execut eUpdat e de tal forma que no toman
argumentos. Los formatos de Statement de estos mtodos (los formatos que toman
una sentencia SQL como argumento) no deberan usarse nunca con objetos
PreparedStatement.

6.1.1 Creacin de objetos PreparedStatement
El siguiente ejemplo, donde con es un objeto Connection, crea un objeto
PreparedStatement conteniendo una sentencia SQL con dos encajes para
parmetros IN.

Pr epar edSt at ement pst mt = con. pr epar eSt at ement (
" UPDATE t abl e4 SET m= ? WHERE x = ?" ) ;
36

El objeto pst mt contiene ahora la sentencia UPDATE t abl e4 SET m= ? WHERE
x = ? , que ya ha sido enviada a la base de datos y ha sido preparada para su
ejecucin.

6.1.2 Pasar parmetros IN

Antes de que un objeto Pr epar edSt at ement sea ejecutado debe fijarse el valor de
cada encaje ?. Se hace esto mediante la llamada a un mtodo set XXX, donde
XXX es el tipo apropiado para el parmetro. Por ejemplo, si el parmetro tiene un
tipo Java l ong, el mtodo a usar ser set Long. El primero de los argumentos del
mtodo set XXX es la posicin ordinal del parmetro a fijar, y el segundo argumento
es el valor que queremos que adquiera el parmetro. Por ejemplo, lo siguiente fija el
primer parmetro a 123456789 y el segundo a 10000000.

pst mt . set Long( 1, 123456789) ;
pst mt . set Long( 2, 100000000) ;

Una vez que el valor ha sido fijado para una sentencia dada, puede usarse para
mltiples ejecuciones de esa sentencia hasta que se limpie mediante el mtodo
ClearParameters.

En el modo por defecto para una conexin (modo auto-commit activo), cada
sentencia es conmitada o rechazada automticamente cuando se completa.

El mismo objeto Pr epar edSt at ement puede ejecutarse mltiples veces si la base
de datos subyacente y el driver guardan las sentencias abiertas despus que hayan
sido conmitadas. A menos que se de este caso, no hay un punto en el que intentar
mejorar el rendimiento mediante el uso de objetos Pr epar edSt at ement en lugar
de objetos St at ement .

Usando pstmt, el objeto Pr epar edSt at ement creado anteriormente, el siguiente
ejemplo ilustra como fijar los parmetros de los dos encajes y ejecutar pst mt 10
veces. Como se ha mencionado anteriormente, la base de datos no debe cerrar
pst mt . En este ejemplo, el primer parmetro se fija a Hi y permanece constante.
El segundo parmetro se fija a un valor diferente en cada ejecucin mediante el
bucle for comenzando en 0 y terminando en 9.

pst mt . set St r i ng( 1, " Hi " ) ;
f or ( i nt i = 0; i < 10; i ++) {
pst mt . set I nt ( 2, i ) ;
i nt r owCount = pst mt . execut eUpdat e( ) ;
}
37
6.1.3 Conformidad de tipos de datos en parmetros IN

El XXX en los mtodos set XXX son tipos Java. Estos son los tipos implcitos de
JDBC (tipos genricos SQL) porque el driver mapear el tipo Java en su
correspondiente tipo JDBC (ver la seccin 8 para ms informacin sobre el mapeo
de tipos), y envan ese tipo JDBC a la base de datos. El siguiente ejemplo fija el
segundo parmetro del objeto Pr epar edSt at ement pst mt a 44 con un tipo Java
shor t .

pst mt . set Shor t ( 2, 44) ;

El driver enviar 44 a la base de datos como un JDBC SMALLINT que es el mapeo
estndar para un short Java.

Es responsabilidad del programador asegurarse que el tipo Java en cada parmetro
IN mapeado a un tipo de JDBC es compatible con el tipo de dato JDBC esperado
por la base de datos. Consideremos el caso en el que la base de datos espera un
tipo de datos SMALLINT. SI se usa el mtodo setByte , el driver enviar un JDBC
TINYINT a la base de datos. Esto probablemente funcionar porque muchas bases
de datos convierten un tipo relacionado en otro, y, generalmente, un tipo TINYINT
puede ser usado donde un SMALLINT. De cualquier modo, una aplicacin que
trabaje para la mayora de bases de datos posibles, es preferible que use tipos Java
que se correspondan con el tipo exacto JDBC esperado por la base de datos. Si el
tipo esperado es SMALLINT, usar setShort en vez de setByte y esto har la
aplicacin ms portable.

6.1.4 Usar setObject

Un programador puede convertir explicitamente un parmetro de entrada en un tipo
particular JDBC mediante el uso de set Obj ect . Este mtodo puede tomar un
tercer argumento que especifica el tipo JDBC objetivo. EL driver convertir el
Obj ect Java al tipo especificado JDBC anten de enviarlo a la base de datos.

Si no se da el tipo JDBC, el driver simplemente mapear el Obj ect Java a su tipo
JDBC por defecto (usando la tabla de la seccin 8) y lo enviar a la base de datos.
Esto es similar a lo que ocurre con los mtodos set XXX regulares. En ambos casos,
el driver mapea el tipo Java del valor al tipo JDBC apropiado antes de enviarlo a la
base de datos. La diferencia est en que los mtodos set XXX usan el mapeo
estndar de los tipos Java a tipos JDBC, mientras que el mtodo usa el mapeo
desde typos Object de Java a tipos JDBC (ver la tabla en la seccin 8.6.4).
38

La capacidad de el mtodo set Obj ect para aceptar cualquier objeto Java permite
a una aplicacin ser genrica y aceptar entradas para un parmetro en tiempo de
ejecucin. En esta situacin el tipo de entrada no es conocido cuando la aplicacin
es compilada. Mediante el uso de set Obj ect , la aplicacin puede aceptar
cualquier tipo de objeto Java como entrada al tipo JDBC esperado por la base de
datos. La tabla de la seccin 8.6.5 muestra todas las posibles conversiones qiue
set Obj ect puede realizar.

6.1.5 Envo de JDBC NULL como un parmetro IN

El mtodo set Nul l permite a los programadores enviar valores JDBC NULL a la
base de datos como un parmetro I N. Notese de cualquier modo, que debe
especificarse el tipo del parmetro.

Tambin se enviar un JDBC NULL a la base de datos cuando un valor Java nul l
se pasa mediante un mtodo set XXX (si los acepta los objetos Java como
argumentos). El mtodo set Obj ect , en cualquier caso, puede tomar un valor null
nicamente si se ha especificado el tipo JDBC.

6.1.6 Envio de parmetros IN muy grandes.

Los mtodos set Byt es y set St r i ng son capaces de enviar cantidades ilimitadas
de datos. De cualquier forma, a veces los programadores prefiern pasar los grandes
blobs de datos en pequeos pedazos. Esto puede realizarse fijando un parmetro
IN a una corriente Java. Cuando se ejecuta la sentencia, el driver JDBC realizar
repetidas llamadas a esta corriente de entrada, leyendo sus contenidos y
transmitiendo estos contenidos con los datos actuales de los parmetros.

JDBC suministra tres mtodos para fijar parmetros IN a corrientes de entrada.
set Bi nar ySt r eampara corrientes que contienen bytes, set Asci i St r eampara
corrientes que contienen caracteres ASCII y set Uni codeSt r eampara corrientes
que contienen caracteres Unicode. Estos mtodos toman un argumento mas que los
otros mtodos setXXX porque debe especificarse la longitud de la corriente. Esto es
necesario porque algunas bases de datos necesitan conocer el tamao total de los
datos a transferir antes de enviarlos.

El siguiente ejemplo ilustra el uso de una corriente para enviar el contenido de un
fichero en un parmetro IN
39

j ava. i o. Fi l e f i l e = new j ava. i o. Fi l e( " / t mp/ dat a" ) ;
i nt f i l eLengt h = f i l e. l engt h( ) ;
j ava. i o. I nput St r eamf i n = new j ava. i o. Fi l eI nput St r eam( f i l e) ;
j ava. sql . Pr epar edSt at ement pst mt = con. pr epar eSt at ement (
" UPDATE Tabl e5 SET st uf f = ? WHERE i ndex = 4" ) ;
pst mt . set Bi nar ySt r eam( 1, f i n, f i l eLengt h) ;
pst mt . execut eUpdat e( ) ;

Cuando la sentencia se ejecuta, la corriente de entrada fin ser llamada
repetidamente hasta completar los datos.

7. LA CLASE CallableStatement

7.1 Vista Preliminar

Un objeto CallableStatement provee de una forma estndar de llamar a
procedimientos almacenados de la base de datos. Un procedimiento almacenado se
encuentra en la base de datos. La llamada al procedimiento es lo que contiene el
objeto CallableStatement. Esta llamada se escribe en una sintaxis de escape que
puede tomar una de dos formas: una formato con un parmetro resultado y el otro
sin el. (Ver la seccin 4 para mas informacin sobre la sintaxis de escape). Un
parmetro resultado, un tipo de parmetro OUT, es el valor devuelto por el
procedimiento almacenado. Ambos formatos pueden tener un nmero variable de
parmetros de entrada (parmetros IN), de salida (parmetros OUT) o mbos
(parmetros INOUT). Un interrogante sirve como anclaje para cada parmetro.

La sintaxis para invocar un procedimiento almacenado en JDBC se muestra a
continuacin: Notar que los corchetes indican que lo que se encuenta contenido en
ellos es opcional, no ofroma parte de la sintaxis.

{cal l pr ocedur e_name[ ( ?, ?, . . . ) ] }

La sintaxis para un procedimiento que devuelve un resultado es:

{? = cal l pr ocedur e_name[ ( ?, ?, . . . ) ] }

La sintaxis para un procedimiento almacenado sin parmetros se parece a algo
como:

{cal l pr ocedur e_name}

Normalmente, alquien que crea un objeto Cal l abl eSt at ement debera saber ya si
la DBMS que est usando soporta o no procedimientos almacenados y que son
estos. Si alguien necesita chequearlo de cualquier modo, existen varios mtodos de
Dat abaseMet aDat a que suministran tal informacin. Por ejemplo, el mtodo
suppor t sSt or edPr ocedur es devolver t r ue si la DBMS soporta llamadas a
40
procedimientos almacenados y el mtodo get Pr ocedur es devolver una
descripcin de los procedimientos almacenados disponibles.

Cal l abl eSt at ement hereda los mtodos de St at ement , los cuales tratan
sentencias SQL en general, y tambin hereda los mtodos de
Pr epar edSt at ement , que tratan los parmetros IN. Todos los mtodos definidos
para Cal l abl eSt at ement tratan los parmetros OUT o los aspectos de salida de
los parmetros INOUT: registro de los tipos JDBC (tipos genricos SQL) de los
parmetros OUT, recuperacin de valores desde ellos o chequear si el valor
devuelto es un JDBC NULL.

7.1.1 Crear objetos CallableStatement

Los objetos Cal l abl eSt at ement se crean con el mtodo pr epar eCal l de
Connect i on. El siguiente ejemplo crea una instancia de Cal l abl eSt at ement
que contiene una llamada al procedimiento almacenado get Test Dat a, con dos
argumentos y no devuelve resultados.

Cal l abl eSt at ement cst mt = con. pr epar eCal l (
" {cal l get Test Dat a( ?, ?) }" ) ;

donde los encajes ? son parmetros IN, OUT INOUT dependiendo del
procedimiento get Test Dat a.

7.1.2 Parmetros IN y OUT

El paso de valor para cualquier parmetro IN de un objeto Cal l abl eSt at ement
se realiza mediante los mtodos set XXX heredados de Pr epar edSt at ement . El
tipo de el valor a pasar se determina por el mtodo set XXX a usar (set Fl oat para
pasar un valor f l oat , y as).

Si el procedimiento almacenado devuelve parmetros OUT, el tipo JDBC de cada
parmetro OUT debe ser registrado antes de que el objeto Cal l abl eSt at ement
sea ejecutado (Esto es necesario porque algunas DBMS necesitan el tipo JDBC). El
registro del tipo JDBC se realiza mediante el mtodo r egi st er Out Par amet er s.
Despus que la sentencia ha sido ejecutada, los mtodos get XXX de
Cal l abl eSt at ement recuperan los valores de los parmetros. El mtodo correcto
get XXX a usar es el tipo Java que corresponde al tipo JDBC registrado para el
parmetro. (El mapeo estndar para los tipos JDBC a tipos Java se muestra en la
tabla de la seccin 8.6.1). En otras palabras r egi st er Out Par amet er usa un tipo
41
JDBC (por tanto coincide con el tipo con el tipo JDBC que la base de datos
devolver) y get XXX casts este a un tipo Java.

Para ilustrar esto, el siguiente ejemplo registra los parmetros OUT, ejecuta el
procedimiento almacenado llamado por cst mt y recupera los valores devueltos en
los parmetros OUT. El mtodo get Byt e recupera un byte Java de el primer
parmetro, y get Bi gDeci mal recupera un objeto Bi gDeci mal (con tres dgitos
despus del punto decimal) del segundo parmetro OUT:

Cal l abl eSt at ement cst mt = con. pr epar eCal l (
" {cal l get Test Dat a( ?, ?) }" ) ;
cst mt . r egi st er Out Par amet er ( 1, j ava. sql . Types. TI NYI NT) ;
cst mt . r egi st er Out Par amet er ( 2, j ava. sql . Types. DECI MAL, 3) ;
cst mt . execut eQuer y( ) ;
byt e x = cst mt . get Byt e( 1) ;
j ava. mat h. Bi gDeci mal n = cst mt . get Bi gDeci mal ( 2, 3) ;

De modo distinto a ResultSet, CallableStatement no tiene un mecanismo especial
para recuperar grandes valores OUT incrementalmente.

7.1.3 Parmetros INOUT

Son parmetros que suminstran entradas as como aceptan salidas. Estos requieren
llamar a los mtodos apropiados set XXX (heredados de Pr epar edSt at ement )
adems de llamar al mtodo r egi st er Out Par amet er . Los mtodos set XXX fijan
los valores como parmetros de entrada y r egi st er Out Par amet er registra sus
tipos JDBC como parmetros de salida. El mtodo set XXX suminstra un valor Java
que el driver convierte en un valor JDBC antes de enviarlo a la base de datos.

El tipo JDBC del valor IN y el tipo JDBC para suminstrado al mtodo
r egi st er Out Par amet er debe ser el mismo. Luego, para recuperar el valor de
salida, se usa el mtodo apropiado get XXX. Por ejemplo, un parmetro cuyo tipo
Java es byt e debera usar el mtodo set Byt e para asignar el valor de entrada,
debera suplir un TINYINT como tipo JDBC para r egi st er Out Par amet er , y
debera usar get Byt e para recuperar el valor de salida (Seccion 8, da ms
informacin y contiene tablas de tipos mapeados).

El siguiente ejemplo asume que existe un procedimiento almacenado r evi seTot al
con un nico parmetro INOUT. El mtodo set Byt e fija el valor del parmetro a 25
que es el que el driver enviar a la base de datos como un JDBC TINYINT. Despus
r egi st er Out Par amet er registrar el parmetro como un JDBC TINYINT. Luego
que el procedimiento sea ejecutado se devolver un nuevo JDBC TINYINT y el
mtodo get Byt e lo recuperar como un nuevo valor byt e Java.
42

Cal l abl eSt at ement cst mt = con. pr epar eCal l (
" {cal l r evi seTot al ( ?) }" ) ;
cst mt . set Byt e( 1, 25) ;
cst mt . r egi st er Out Par amet er ( 1, j ava. sql . Types. TI NYI NT) ;
cst mt . execut eUpdat e( ) ;
byt e x = cst mt . get Byt e( 1) ;

7.1.4 Recuperar parmetros OUT despus de resultados

Dadas las limitaciones impuestas pro algunas DBMS, se recomienda en aras de la
mxima portabilidad, que todos los resultados generados por la ejecucin de un
objeto Cal l abl eSt at ement deberan recuperarse antes que los parmetros OUT
usando los mtodos Cal l abl eSt at ement .get XXX.

Si un objeto Cal l abl eSt at ement devuelve mltiples objetos Resul t Set
(mediante una llamada al mtodo execut e), todos los resultados deben
recuperarse antes que los parmetros OUT. En este caso, debe asegurarse de que
todos los resultados han sido accedidos, los mtodos de St at ement
get Resul t Set , get Updat eCount y get Mor eResul t s necesitan ser llamados
hasta que no haya ms resultados.

Despus de hecho esto, los valores de los parmetros OUT pueden ser
recuperados mediante los mtodos Cal l abl eSt at ement . get XXX.

7.1.5 Recuperar valores NULL en parmetros OUT

El valor devuelto en un parmetro OUT puede ser JDBC NULL. Cuando esto ocurre,
le valor JDBC NULL se convertir de forma que el valor devuelto por el mtodo
get XXX sea null, 0 o false dependiendo del tipo del mtodo get XXX usado.Como
con los objetos Resul t Set , la nica manera de saber si un valor de 0 o false fue
originalmente NULL JDBC es testear el mtodo wasNul l , que devuelve true si el
ltimo valor ledo por un mtodo getXXX fue JDBC NULL y false en caso contrario.
La seccin 5 contiene ms informacin al respecto.

43
9. EJEMPLO DE CODIGO

/ / The f ol l owi ng code can be used as a t empl at e. Si mpl y
/ / subst i t ut e t he appr opr i at e ur l , l ogi n, and passwor d, and t hen
subst i t ut e t he
/ / SQL st at ement you want t o send t o t he dat abase.



/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
/ /
/ / Modul e: Si mpl eSel ect . j ava
/ /
/ / Descr i pt i on: Test pr ogr amf or ODBC API i nt er f ace. Thi s j ava
appl i cat i on
/ / wi l l connect t o a J DBC dr i ver , i ssue a sel ect st at ement
/ / and di spl ay al l r esul t col umns and r ows
/ /
/ / Pr oduct : J DBC t o ODBC Br i dge
/ /
/ / Aut hor : Kar l Moss
/ /
/ / Dat e: Febr uar y, 1996
/ /
/ / Copyr i ght : 1990- 1996 I NTERSOLV, I nc.
/ / Thi s sof t war e cont ai ns conf i dent i al and pr opr i et ar y
/ / i nf or mat i on of I NTERSOLV, I nc.
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -

i mpor t j ava. net . URL;
i mpor t j ava. sql . *;

cl ass Si mpl eSel ect {

publ i c st at i c voi d mai n ( St r i ng ar gs[ ] ) {
St r i ng ur l = " j dbc: odbc: my- dsn" ;
St r i ng quer y = " SELECT * FROM emp" ;

t r y {

/ / Load t he j dbc- odbc br i dge dr i ver

Cl ass. f or Name ( " sun. j dbc. odbc. J dbcOdbcDr i ver " ) ;

Dr i ver Manager . set LogSt r eam( Syst em. out ) ;

/ / At t empt t o connect t o a dr i ver . Each one
/ / of t he r egi st er ed dr i ver s wi l l be l oaded unt i l
/ / one i s f ound t hat can pr ocess t hi s URL

Connect i on con = Dr i ver Manager . get Connect i on (
ur l , " my- user " , " my- passwd" ) ;
44


/ / I f we wer e unabl e t o connect , an except i on
/ / woul d have been t hr own. So, i f we get her e,
/ / we ar e successf ul l y connect ed t o t he URL

/ / Check f or , and di spl ay and war ni ngs gener at ed
/ / by t he connect .

checkFor War ni ng ( con. get War ni ngs ( ) ) ;

/ / Get t he Dat abaseMet aDat a obj ect and di spl ay
/ / some i nf or mat i on about t he connect i on

Dat abaseMet aDat a dma = con. get Met aDat a ( ) ;

Syst em. out . pr i nt l n( " \ nConnect ed t o " + dma. get URL( ) ) ;
Syst em. out . pr i nt l n( " Dr i ver " +
dma. get Dr i ver Name( ) ) ;
Syst em. out . pr i nt l n( " Ver si on " +
dma. get Dr i ver Ver si on( ) ) ;
Syst em. out . pr i nt l n( " " ) ;

/ / Cr eat e a St at ement obj ect so we can submi t
/ / SQL st at ement s t o t he dr i ver

St at ement st mt = con. cr eat eSt at ement ( ) ;

/ / Submi t a quer y, cr eat i ng a Resul t Set obj ect

Resul t Set r s = st mt . execut eQuer y ( quer y) ;

/ / Di spl ay al l col umns and r ows f r omt he r esul t set

di spResul t Set ( r s) ;

/ / Cl ose t he r esul t set

r s. cl ose( ) ;

/ / Cl ose t he st at ement

st mt . cl ose( ) ;

/ / Cl ose t he connect i on

con. cl ose( ) ;
}
cat ch ( SQLExcept i on ex) {

/ / A SQLExcept i on was gener at ed. Cat ch i t and
/ / di spl ay t he er r or i nf or mat i on. Not e t hat t her e
/ / coul d be mul t i pl e er r or obj ect s chai ned
/ / t oget her
45


Syst em. out . pr i nt l n ( " \ n*** SQLExcept i on caught ***\ n" ) ;

whi l e ( ex ! = nul l ) {
Syst em. out . pr i nt l n ( " SQLSt at e: " +
ex. get SQLSt at e ( ) ) ;
Syst em. out . pr i nt l n ( " Message: " + ex. get Message ( ) ) ;
Syst em. out . pr i nt l n ( " Vendor : " +
ex. get Er r or Code ( ) ) ;
ex = ex. get Next Except i on ( ) ;
Syst em. out . pr i nt l n ( " " ) ;
}
}
cat ch ( j ava. l ang. Except i on ex) {

/ / Got some ot her t ype of except i on. Dump i t .

ex. pr i nt St ackTr ace ( ) ;
}
}

/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / checkFor War ni ng
/ / Checks f or and di spl ays war ni ngs. Ret ur ns t r ue i f a war ni ng
/ / exi st ed
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

pr i vat e st at i c bool ean checkFor War ni ng ( SQLWar ni ng war n)
t hr ows SQLExcept i on {
bool ean r c = f al se;

/ / I f a SQLWar ni ng obj ect was gi ven, di spl ay t he
/ / war ni ng messages. Not e t hat t her e coul d be
/ / mul t i pl e war ni ngs chai ned t oget her

i f ( war n ! = nul l ) {
Syst em. out . pr i nt l n ( " \ n *** War ni ng ***\ n" ) ;
r c = t r ue;
whi l e ( war n ! = nul l ) {
Syst em. out . pr i nt l n ( " SQLSt at e: " +
war n. get SQLSt at e ( ) ) ;
Syst em. out . pr i nt l n ( " Message: " +
war n. get Message ( ) ) ;
Syst em. out . pr i nt l n ( " Vendor : " +
war n. get Er r or Code ( ) ) ;
Syst em. out . pr i nt l n ( " " ) ;
war n = war n. get Next War ni ng ( ) ;
}
}
r et ur n r c;
}

46
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / di spResul t Set
/ / Di spl ays al l col umns and r ows i n t he gi ven r esul t set
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

pr i vat e st at i c voi d di spResul t Set ( Resul t Set r s)
t hr ows SQLExcept i on
{
i nt i ;

/ / Get t he Resul t Set Met aDat a. Thi s wi l l be used f or
/ / t he col umn headi ngs

Resul t Set Met aDat a r smd = r s. get Met aDat a ( ) ;

/ / Get t he number of col umns i n t he r esul t set

i nt numCol s = r smd. get Col umnCount ( ) ;

/ / Di spl ay col umn headi ngs

f or ( i =1; i <=numCol s; i ++) {
i f ( i > 1) Syst em. out . pr i nt ( " , " ) ;
Syst em. out . pr i nt ( r smd. get Col umnLabel ( i ) ) ;
}
Syst em. out . pr i nt l n( " " ) ;

/ / Di spl ay dat a, f et chi ng unt i l end of t he r esul t set

bool ean mor e = r s. next ( ) ;
whi l e ( mor e) {

/ / Loop t hr ough each col umn, get t i ng t he
/ / col umn dat a and di spl ayi ng

f or ( i =1; i <=numCol s; i ++) {
i f ( i > 1) Syst em. out . pr i nt ( " , " ) ;
Syst em. out . pr i nt ( r s. get St r i ng( i ) ) ;
}
Syst em. out . pr i nt l n( " " ) ;

/ / Fet ch t he next r esul t set r ow

mor e = r s. next ( ) ;
}
}
}

También podría gustarte