Existen varios tipos de datos nuevos denominados tipos de datos SQL3 que se suministran en la base de datos de iSeries con el e-PACK de V4R4. Java Database Connectivity (JDBC) 2.0 y superior proporciona soporte para trabajar con estos tipos de datos que forman parte del estándar SQL99.
Los tipos de datos SQL3 proporcionan un enorme nivel de flexibilidad. Son perfectos para almacenar objetos Java serializados, documentos XML (Extensible Markup Language) y datos multimedia, como por ejemplo, canciones, imágenes de producto, fotografías de empleados y clips de vídeo.
Tipos distintivos (distinct): El tipo distintivo es un tipo definido por usuario que se basa en un tipo de base de datos estándar. Por ejemplo, puede definir un tipo de Número de Seguridad Social (Social Security Number), SSN, que internamente sea CHAR(9). La siguiente sentencia SQL crea un tipo DISTINCT de ese tipo.
CREATE DISTINCT TYPE CUJOSQL.SSN AS CHAR(9)
Un tipo distintivo se correlaciona siempre con un tipo de datos incorporado. Para obtener más información acerca de cómo, cuándo y dónde utilizar tipos distintivos en el contexto de SQL, consulte los manuales de SQL.
Para utilizar tipos distintivos en JDBC, se accede a ellos de la misma forma que a un tipo subyacente. El método getUDTs es un método nuevo que permite consultar los tipos distintivos que están disponibles en el sistema. Este programa de ejemplo muestra lo siguiente:
v La creación de un tipo distintivo. v La creación de una tabla que lo utiliza.
v La utilización de una PreparedStatement para establecer un parámetro de tipo distintivo.
v La utilización de un ResultSet para devolver un tipo distintivo.
v La utilización de la llamada de la API (Interfaz del programa de aplicación) de metadatos a getUDTs para obtener información acerca de un tipo distintivo.
Objetos grandes: Existen tres tipos de Objetos grandes (LOB):
v Objetos grandes binarios (BLOB)
v Objetos grandes de tipo carácter (CLOB)
Los DBCLOB son parecidos a los CLOB, excepto en su representación de almacenamiento interno de los datos de tipo carácter. Debido a que Java y JDBC externalizan todos los datos de tipo carácter en forma de Unicode, en JDBC sólo existe soporte para los CLOB. Los DBCLOB funcionan de forma
intercambiable con el soporte de CLOB desde una perspectiva JDBC.
Objetos grandes binarios: En muchos aspectos, una columna de Objeto grande binario (BLOB) es parecida a una columna CHAR FOR BIT DATA que puede convertirse en grande. En estas columnas puede almacenar cualquier objeto que pueda representarse como una corriente de bytes no convertidos. Las columnas BLOB se utilizan con frecuencia para almacenar objetos Java serializados, imágenes, canciones y otros datos binarios.
Puede utilizar los BLOB de la misma forma que otros tipos de base de datos estándar. Puede pasarlos a procedimientos almacenados, utilizarlos en sentencias preparadas y actualizarlos en conjuntos de resultados. La clase PreparedStatement contiene un método setBlob para pasar BLOB a la base de datos, y la clase ResultSet añade una clase getBlob para recuperarlos de la base de datos. Un BLOB se representa en un programa Java mediante un objeto BLOB que es una interfaz JDBC.
Consulte el apartado Escribir código que utilice BLOB para obtener más información acerca de cómo utilizar los BLOB.
Objetos grandes de tipo carácter: Los Objetos grandes de tipo carácter (CLOB) son el complemento de datos de tipo carácter de los BLOB. En lugar de almacenar datos en la base de datos sin conversión, los datos se almacenan en la base de datos en forma de texto y se procesan de la misma forma que una columna CHAR. Al igual que para los BLOB, JDBC 2.0 proporciona funciones para tratar directamente con los CLOB. La interfaz PreparedStatement contiene un método setClob y la interfaz ResultSet contiene un método getClob.
Consulte el apartado Escribir código que utilice CLOB para obtener más información acerca de cómo utilizar los CLOB.
Aunque las columnas BLOB y CLOB funcionan como las columnas CHAR FOR BIT DATA y CHAR, así es como funcionan conceptualmente desde la perspectiva del usuario externo. Internamente, son distintos; debido al tamaño potencialmente enorme de las columnas de Objeto grande (LOB), generalmente se trabaja indirectamente con los datos. Por ejemplo, cuando se extrae un bloque de filas de la base de datos, no se mueve un bloque de LOB al ResultSet. En lugar de ello, se mueven punteros denominados localizadores de LOB (es decir, enteros de cuatro bytes) a ResultSet. Sin embargo, no es necesario, tener conocimientos acerca de los localizadores al trabajar con los LOB en JDBC.
Enlaces de datos (Datalinks): Los enlaces de datos son valores encapsulados que contienen una referencia lógica de la base de datos a un archivo almacenado fuera de la misma. Los enlaces de datos se representan y utilizan desde una perspectiva JDBC de dos maneras diferentes, dependiendo de si se utiliza JDBC 2.0 o anterior, o si se utiliza JDBC 3.0 o posterior.
Consulte el apartado Escribir código que utilice Enlaces de datos para obtener más información acerca de cómo utilizar los Enlaces de datos.
Tipos de datos SQL3 no soportados: Existen otros tipos de datos SQL3 que se han definido y para los que la API de JDBC proporciona soporte. Son ARRAY, REF y STRUCT. Actualmente, los servidores iSeries no soportan estos tipos. Por tanto, el controlador JDBC no proporciona ninguna forma de soporte para ellos.
Existen diversas tareas que pueden realizarse con columnas BLOB (Objeto grande binario) de base de datos mediante la API (Interfaz de programación de aplicaciones) de Java Database Connectivity (JDBC). Los temas que siguen describen brevemente estas tareas e incluyen ejemplos de cómo realizarlas.
Leer los BLOB de la base de datos e insertar BLOB en la base de datos: Con la API de JDBC, existen formas de extraer los BLOB de la base de datos y formas de colocar BLOB en la base de datos. Sin embargo, no existe ninguna forma estandarizada para crear un objeto Blob. Esto no representa ningún problema si la base de datos ya está llena de BLOB, pero sí lo es si desea trabajar con los BLOB desde cero mediante JDBC. En lugar de definir un constructor para las interfaces Blob y Clob de la API de JDBC, se proporciona soporte para colocar los BLOB en la base de datos y extraerlos de la base de datos directamente como otros tipos. Por ejemplo, el método setBinaryStream puede trabajar con una columna de base de datos de tipo Blob. Este ejemplo muestra algunas de las formas comunes de colocar un BLOB en la base de datos o recuperarlo de la misma.
Trabajar con la API de objeto Blob: Los BLOB se definen en JDBC como una interfaz de la que los diversos controladores proporcionan implementaciones. Esta interfaz contiene una serie de métodos que pueden utilizarse para interactuar con el objeto Blob. Este ejemplo muestra algunas de las tareas
comunes que pueden realizarse utilizando esta API. Consulte el Javadoc de JDBC para obtener una lista completa de los métodos disponibles en el objeto Blob.
Utilizar el soporte de JDBC 3.0 para actualizar BLOB: En JDBC 3.0 existe soporte para efectuar cambios en objetos LOB. Estos cambios pueden almacenarse en columnas BLOB de la base de datos. Este ejemplo muestra algunas de las tareas que pueden realizarse con el soporte BLOB de JDBC 3.0.
Ejemplo: BLOB:
Este es un ejemplo de cómo puede colocarse un BLOB en la base de datos o recuperarse de la misma.
Ejemplo: BLOB
Nota: lea el apartado Declaración de limitación de responsabilidad sobre el código de ejemplo para obtener información legal importante.
///////////////////////////////////////// // PutGetBlobs es una aplicación de ejemplo // que muestra cómo trabajar con la API de JDBC // para colocar objetos BLOB en columnas de base // de datos y obtenerlos desde ellas.
//
// Los resultados de la ejecución de este programa // provocan la inserción de dos valores de BLOB // en una tabla nueva. Ambos son idénticos // y contienen 500k de datos de byte // aleatorios.
///////////////////////////////////////// import java.sql.*;
import java.util.Random; public class PutGetBlobs {
public static void main(String[] args) throws SQLException
{
// Registrar el controlador JDBC nativo. try {
Class.forName("com.ibm.db2.jdbc.app.DB2Driver"); } catch (Exception e) {
}
// Establecer una conexión y una sentencia con las que trabajar. Connection c = DriverManager.getConnection("jdbc:db2:*local"); Statement s = c.createStatement();
// Borrar ejecuciones anteriores de esta aplicación. try {
s.executeUpdate("DROP TABLE CUJOSQL.BLOBTABLE"); } catch (SQLException e) {
// Ignorarlo y suponer que la tabla no existía. }
// Crear una tabla con una columna BLOB. El tamaño de columna BLOB // por omisión es de 1 MB.
s.executeUpdate("CREATE TABLE CUJOSQL.BLOBTABLE (COL1 BLOB)"); // Crear un objeto PreparedStatement que permita colocar // un nuevo objeto Blob en la base de datos.
PreparedStatement ps = c.prepareStatement("INSERT INTO CUJOSQL.BLOBTABLE VALUES(?)"); // Crear un valor BLOB grande...
Random random = new Random ();
byte [] inByteArray = new byte[500000]; random.nextBytes (inByteArray);
// Establecer el parámetro PreparedStatement. Nota: no es portable // a todos los controladores JDBC. Los controladores JDBC no // tienen soporte al utilizar setBytes para columnas BLOB. Se
// utiliza para permitir la generación de nuevos BLOB. También permite
// a los controladores JDBC 1.0 trabajar con columnas que contienen datos BLOB. ps.setBytes(1, inByteArray);
// Procesar la sentencia, insertando el BLOB en la base de datos. ps.executeUpdate();
// Procesar una consulta y obtener el BLOB que se acaba de insertar // de la base de datos como objeto Blob.
ResultSet rs = s.executeQuery("SELECT * FROM CUJOSQL.BLOBTABLE"); rs.next();
Blob blob = rs.getBlob(1);
// Colocar de nuevo ese Blob en la base de datos mediante // la PreparedStatement.
ps.setBlob(1, blob); ps.execute();
c.close(); // El cierre de la conexión también cierra stmt y rs. }
}
Ejemplo: actualizar BLOB:
Este es un ejemplo de cómo actualizar BLOB en las aplicaciones.
Ejemplo: actualizar BLOB
Nota: lea el apartado Declaración de limitación de responsabilidad sobre el código de ejemplo para obtener información legal importante.
///////////////////////////////////////// // UpdateBlobs es una aplicación de ejemplo // que muestra algunas de las API que proporcionan // soporte para cambiar objetos Blob
// y reflejar esos cambios en la // base de datos.
//
// Este programa debe ejecutarse después de // finalizar el programa PutGetBlobs. ///////////////////////////////////////// import java.sql.*;
public class UpdateBlobs {
public static void main(String[] args) throws SQLException
{
// Registrar el controlador JDBC nativo. try {
Class.forName("com.ibm.db2.jdbc.app.DB2Driver"); } catch (Exception e) {
System.exit(1); // Error de configuración. }
Connection c = DriverManager.getConnection("jdbc:db2:*local"); Statement s = c.createStatement();
ResultSet rs = s.executeQuery("SELECT * FROM CUJOSQL.BLOBTABLE"); rs.next();
Blob blob1 = rs.getBlob(1); rs.next();
Blob blob2 = rs.getBlob(1); // Truncar un BLOB.
blob1.truncate((long) 150000);
System.out.println("La nueva longitud de Blob1 es " + blob1.length()); // Actualizar parte del BLOB con una matriz de bytes nueva.
// El código siguiente obtiene los bytes que están en
// las posiciones 4000-4500 y los establece en las posiciones 500-1000. // Obtener parte del BLOB como matriz de bytes.
byte[] bytes = blob1.getBytes(4000L, 4500); int bytesWritten = blob2.setBytes(500L, bytes);
System.out.println("Los bytes escritos son " + bytesWritten); // Los bytes se encuentran ahora en la posición 500 de blob2 long startInBlob2 = blob2.position(bytes, 1);
System.out.println("encontrado patrón que empieza en la posición " + startInBlob2); c.close(); // El cierre de la conexión también cierra stmt y rs.
} }
Ejemplo: utilizar BLOB:
Este es un ejemplo de cómo utilizar BLOB en las aplicaciones.
Nota: lea el apartado Declaración de limitación de responsabilidad sobre el código de ejemplo para obtener información legal importante.
///////////////////////////////////////// // UseBlobs es una aplicación de ejemplo // que muestra algunas de las API asociadas // con objetos Blob.
//
// Este programa debe ejecutarse después de // finalizar el programa PutGetBlobs. ///////////////////////////////////////// import java.sql.*;
public class UseBlobs {
public static void main(String[] args) throws SQLException
{
// Registrar el controlador JDBC nativo. try {
Class.forName("com.ibm.db2.jdbc.app.DB2Driver"); } catch (Exception e) {
System.exit(1); // Error de configuración. }
Connection c = DriverManager.getConnection("jdbc:db2:*local"); Statement s = c.createStatement();
ResultSet rs = s.executeQuery("SELECT * FROM CUJOSQL.BLOBTABLE"); rs.next();
Blob blob1 = rs.getBlob(1); rs.next();
Blob blob2 = rs.getBlob(1);
// Determinar la longitud de un LOB. long end = blob1.length();
System.out.println("La longitud de Blob1 es " + blob1.length()); // Al trabajar con LOB, toda la indexación relacionada con ellos // se basa en 1, y no en 0 como las series y matrices.
long startingPoint = 450; long endingPoint = 500;
// Obtener parte del BLOB como matriz de bytes.
byte[] outByteArray = blob1.getBytes(startingPoint, (int)endingPoint); // Buscar donde se encuentra en primer lugar un sub-BLOB o matriz de bytes // dentro del BLOB. La configuración de este programa ha colocado dos copias // idénticas de un BLOB aleatorio en la base de datos. Por tanto, la posición // inicial de la matriz de bytes extraída de blob1 puede encontrarse en la // posición inicial de blob2. La excepción sería si previamente hubiera 50 // bytes aleatorios idénticos en los LOB.
long startInBlob2 = blob2.position(outByteArray, 1);
System.out.println("encontrado patrón que empieza en la posición " + startInBlob2); c.close(); // El cierre de la conexión también cierra stmt y rs.
} }
Existen diversas tareas que pueden realizarse con columnas CLOB y DBCLOB de base de datos mediante la API (Interfaz de programación de aplicaciones) de Java Database Connectivity (JDBC). Los temas que siguen describen brevemente estas tareas e incluyen ejemplos de cómo realizarlas.
Leer los CLOB de la base de datos e insertar CLOB en la base de datos: Con la API de JDBC, existen formas de extraer los CLOB de la base de datos y formas de colocar CLOB en la base de datos. Sin embargo, no existe ninguna forma estandarizada para crear un objeto Clob. Esto no representa ningún problema si la base de datos ya está llena de CLOB, pero sí lo es si desea trabajar con los CLOB desde cero mediante JDBC. En lugar de definir un constructor para las interfaces Blob y Clob de la API de JDBC, se proporciona soporte para colocar los CLOB en la base de datos y extraerlos de la base de datos directamente como otros tipos. Por ejemplo, el método setCharacterStream puede trabajar con una columna de base de datos de tipo Clob. Este ejemplo muestra algunas de las formas comunes de colocar un CLOB en la base de datos o recuperarlo de la misma.
Trabajar con la API de objeto Clob: Los CLOB se definen en JDBC como una interfaz de la que los diversos controladores proporcionan implementaciones. Esta interfaz contiene una serie de métodos que pueden utilizarse para interactuar con el objeto Clob. Este ejemplo muestra algunas de las tareas
comunes que pueden realizarse utilizando esta API. Consulte el Javadoc de JDBC para obtener una lista completa de los métodos disponibles en el objeto Clob.
Utilizar el soporte de JDBC 3.0 para actualizar CLOB: En JDBC 3.0 existe soporte para efectuar cambios en objetos LOB. Estos cambios pueden almacenarse en columnas CLOB de la base de datos. Este ejemplo muestra algunas de las tareas que pueden realizarse con el soporte CLOB de JDBC 3.0.
Ejemplo: CLOB:
Este es un ejemplo de cómo puede colocarse un CLOB en la base de datos o recuperarse de la misma.
Ejemplo: CLOB
Nota: lea el apartado Declaración de limitación de responsabilidad sobre el código de ejemplo para obtener información legal importante.
///////////////////////////////////////// // PutGetClobs es una aplicación de ejemplo // que muestra cómo trabajar con la API de JDBC // para colocar objetos CLOB en columnas de base // de datos y obtenerlos desde ellas.
//
// Los resultados de la ejecución de este programa // provocan la inserción de dos valores de CLOB // en una tabla nueva. Ambos son idénticos // y contienen alrededor de 500k de datos // de texto de repetición.
///////////////////////////////////////// import java.sql.*;
public class PutGetClobs {
public static void main(String[] args) throws SQLException
{
// Registrar el controlador JDBC nativo. try {
Class.forName("com.ibm.db2.jdbc.app.DB2Driver"); } catch (Exception e) {
System.exit(1); // Error de configuración. }
// Establecer una conexión y una sentencia con las que trabajar. Connection c = DriverManager.getConnection("jdbc:db2:*local"); Statement s = c.createStatement();
// Borrar ejecuciones anteriores de esta aplicación. try {
s.executeUpdate("DROP TABLE CUJOSQL.CLOBTABLE"); } catch (SQLException e) {
// Ignorarlo y suponer que la tabla no existía. }
// Crear una tabla con una columna CLOB. El tamaño de columna CLOB // por omisión es de 1 MB.
s.executeUpdate("CREATE TABLE CUJOSQL.CLOBTABLE (COL1 CLOB)"); // Crear un objeto PreparedStatement que permita colocar // un nuevo objeto Clob en la base de datos.
PreparedStatement ps = c.prepareStatement("INSERT INTO CUJOSQL.CLOBTABLE VALUES(?)"); // Crear un valor CLOB grande...
StringBuffer buffer = new StringBuffer(500000); while (buffer.length() < 500000) {
buffer.append("All work and no play makes Cujo a dull boy."); }
String clobValue = buffer.toString();
// Establecer el parámetro PreparedStatement. No es portable // a todos los controladores JDBC. Los controladores JDBC no // tienen soporte para setBytes para columnas CLOB. Se realiza para // permitir la generación de nuevos CLOB. También permite
// a los controladores JDBC 1.0 trabajar con columnas que contienen // datos Clob.
ps.setString(1, clobValue);
// Procesar la sentencia, insertando el clob en la base de datos. ps.executeUpdate();
// Procesar una consulta y obtener el CLOB que se acaba de insertar // de la base de datos como objeto Clob.
ResultSet rs = s.executeQuery("SELECT * FROM CUJOSQL.CLOBTABLE"); rs.next();
Clob clob = rs.getClob (1);
// Colocar de nuevo ese Clob en la base de datos mediante // la PreparedStatement.
ps.setClob(1, clob); ps.execute();
c.close(); // El cierre de la conexión también cierra stmt y rs. }
}
Ejemplo: actualizar CLOB:
Este es un ejemplo de cómo actualizar CLOB en las aplicaciones.
Nota: lea el apartado Declaración de limitación de responsabilidad sobre el código de ejemplo para obtener información legal importante.
///////////////////////////////////////// // UpdateClobs es una aplicación de ejemplo // que muestra algunas de las API que proporcionan // soporte para cambiar objetos Clob
// y reflejar esos cambios en la // base de datos.
//
// Este programa debe ejecutarse después de // finalizar el programa PutGetClobs. ///////////////////////////////////////// import java.sql.*;
public class UpdateClobs {
public static void main(String[] args) throws SQLException
{
// Registrar el controlador JDBC nativo. try {
Class.forName("com.ibm.db2.jdbc.app.DB2Driver"); } catch (Exception e) {
System.exit(1); // Error de configuración. }
Connection c = DriverManager.getConnection("jdbc:db2:*local"); Statement s = c.createStatement();
ResultSet rs = s.executeQuery("SELECT * FROM CUJOSQL.CLOBTABLE"); rs.next();
Clob clob1 = rs.getClob(1); rs.next();
Clob clob2 = rs.getClob(1); // Truncar un CLOB.
clob1.truncate((long) 150000);
System.out.println("La nueva longitud de Clob1 es " + clob1.length()); // Actualizar una parte del CLOB con un nuevo valor de tipo String. String value = "Some new data for once";
int charsWritten = clob2.setString(500L, value);
System.out.println("Los caracteres escritos son " + charsWritten); // Los bytes se encuentran en la posición 500 de clob2
long startInClob2 = clob2.position(value, 1);
System.out.println("encontrado patrón que empieza en la posición " + startInClob2); c.close(); // El cierre de la conexión también cierra stmt y rs.
} }
Ejemplo: utilizar CLOB:
Este es un ejemplo de cómo utilizar CLOB en las aplicaciones.
Ejemplo: utilizar CLOB
Nota: lea el apartado Declaración de limitación de responsabilidad sobre el código de ejemplo para obtener información legal importante.
///////////////////////////////////////// // UpdateClobs es una aplicación de ejemplo // que muestra algunas de las API que proporcionan // soporte para cambiar objetos Clob
// y reflejar esos cambios en la // base de datos.
//
// Este programa debe ejecutarse después de // finalizar el programa PutGetClobs. ///////////////////////////////////////// import java.sql.*;
public class UseClobs {
public static void main(String[] args) throws SQLException
{
// Registrar el controlador JDBC nativo. try {
Class.forName("com.ibm.db2.jdbc.app.DB2Driver"); } catch (Exception e) {
System.exit(1); // Error de configuración. }
Connection c = DriverManager.getConnection("jdbc:db2:*local"); Statement s = c.createStatement();
ResultSet rs = s.executeQuery("SELECT * FROM CUJOSQL.CLOBTABLE"); rs.next();
Clob clob1 = rs.getClob(1); rs.next();
Clob clob2 = rs.getClob(1);
// Determinar la longitud de un LOB. long end = clob1.length();
System.out.println("La longitud de Clob1 es " + clob1.length()); // Al trabajar con LOB, toda la indexación relacionada con ellos // se basa en 1, y no en 0 como las series y matrices.
long startingPoint = 450; long endingPoint = 50;
// Obtener parte del CLOB como matriz de bytes.
String outString = clob1.getSubString(startingPoint, (int)endingPoint); System.out.println("La subserie de Clob es " + outString);
// Buscar donde se encuentra en primer lugar un sub-CLOB o serie
// dentro de un CLOB. La configuración de este programa ha colocado dos copias // idénticas de un CLOB repetido en la base de datos. Por tanto, la posición // inicial de la serie extraída de clob1 puede encontrarse en la
// posición inicial de clob2 si la búsqueda empieza cerca de la posición // en la que empieza la serie.
long startInClob2 = clob2.position(outString, 440);
System.out.println("encontrado patrón que empieza en la posición " + startInClob2); c.close(); // El cierre de la conexión también cierra stmt y rs.
} }
Escribir código que utilice Enlaces de datos (Datalinks):
La forma de trabajar con enlaces de datos depende del release con el que se trabaja. En JDBC 3.0,