0% encontró este documento útil (0 votos)
22 vistas69 páginas

3 Manejo de Conectores A Base de Datos

Descargar como pdf o txt
Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1/ 69

Unidad Didáctica 3.

MANEJO DE CONECTORES A

BASES DE DATOS.

Conexiones a bases de datos

Para conectar nuestro programa Java con una base de datos para realizar consultas y
modificaciones, debemos seguir los siguientes pasos:

• Conseguir el driver: Necesitamos un jar con el driver para nuestra base de

datos. Una vez descargado hay que añadirlo a nuestro classpath o las librerías

del entorno de desarrollo que estemos utilizando.

• Registrar el driver: En general esto se hace de forma automática con la

primera llamada a la clase, o bien de forma explícita con una llamada al

método DriverManager.registerDriver().

• Establecer la conexión: Usaremos el método getConnection(), pasando como

parámetros una URL de conexión a la base de datos y usuario y contraseña de

la base de datos.

El API JDBC

JDBC (Java DataBase Connectivity) es un API de Java que permite al programador el


acceso a Bases de Datos usando el lenguaje estándar SQL.

La biblioteca JDBC incluye API para cada una de las tareas mencionadas a
continuación, que están comúnmente asociadas con el uso de la base de datos.

• Establecer la conexión con la base de datos.

• Crear sentencias SQL a esa base de datos.

• Lanzar consultas SQL a esa base de datos.

Campus Impúlsate | [email protected]


• Visualización y modificación de los registros resultantes.

JDBC es una especificación que proporciona un conjunto completo de interfaces que


permite el acceso portable a una base de datos subyacente. Java se puede usar para
escribir diferentes tipos de ejecutables, como por ejemplo:

• Aplicaciones Java

• Applets de Java

• Servlets de Java

• Java ServerPages (JSP)

• Enterprise JavaBeans (EJB).

Todos estos ejecutables diferentes pueden usar un controlador JDBC para acceder a
una base de datos y aprovechar los datos almacenados.

JDBC proporciona las mismas capacidades que ODBC, lo que permitiría que los
programas Java contengan código independiente de la base de datos.

Arquitectura JDBC

La API de JDBC admite modelos de procesamiento de dos y tres niveles para el acceso
a la base de datos pero, en general, la arquitectura JDBC consta de dos capas:

JDBC API: Proporciona la conexión de aplicación a administrador JDBC.

API de controlador JDBC: Esto es compatible con la conexión JDBC de administrador a


controlador.

La API de JDBC utiliza un controlador de controlador y controladores específicos de la


base de datos para proporcionar conectividad transparente a bases de datos
heterogéneas.

El administrador de controladores JDBC garantiza que se utiliza el controlador correcto


para acceder a cada origen de datos. El administrador de controladores es capaz de
soportar múltiples controladores concurrentes conectados a múltiples bases de datos
heterogéneas.

Como se ha dicho, Java soporta dos modelos de acceso a bases de datos:

Modelo Descripción

Campus Impúlsate | [email protected]


La aplicación Java o el applet se conectan directamente a la base de
datos.

Por tanto, el driver JDBC específico para conectarse con la base de


datos debe residir en el sistema local (dónde se encuentra la
Modelo de
aplicación o el applet). La base de datos puede estar en cualquier otra
dos capas
máquina y se accede a ella mediante la red.

Esta es la configuración típica Cliente/Servidor. El programa cliente


envía instrucciones SQL a la base de datos, ésta los procesa y envía
los resultados de vuelta a la aplicación.

Las instrucciones son enviadas a una capa intermedia entre Cliente y


Servidor, que es la que se encarga de enviar las sentencias SQL a la
base de datos y recoger los resultados.
Modelo de
tres capas Los drivers JDBC no tienen por qué residir en la máquina local.

Esta es la configuración típica en Internet, a través de las páginas


ASP, los servlets y demás tecnologías.

El administrador del controlador con respecto a los controladores JDBC y la aplicación


Java:

Arquitectura JDBC

Componentes comunes de JDBC

Campus Impúlsate | [email protected]


La API JDBC proporciona las siguientes interfaces y clases:

• DriverManager: Esta clase administra una lista de controladores de bases de

datos. Coincide con las solicitudes de conexión de la aplicación java con el

controlador de base de datos adecuado mediante el protocolo secundario de

comunicación. El primer controlador que reconoce un cierto subprotocolo bajo

JDBC se usará para establecer una conexión de base de datos.

• Controlador: Esta interfaz maneja las comunicaciones con el servidor de la

base de datos. La interacción directa con los objetos de Driver es rara. En su

lugar, utilizaremos objetos DriverManager, que maneja objetos de este tipo.

También abstrae los detalles asociados con el trabajo con objetos Driver.

• Connection: Interfaz con todos los métodos para contactar una base de datos.

El objeto de conexión representa el contexto de comunicación, es decir, toda la

comunicación con la base de datos se realiza a través del objeto de conexión

solamente.

• Statement: Utiliza objetos creados desde esta interfaz para enviar las

sentencias de SQL a la base de datos. Algunas interfaces derivadas aceptan

parámetros además de ejecutar procedimientos almacenados.

• ResultSet: Estos objetos contienen datos recuperados de una base de datos

después de ejecutar una consulta SQL utilizando objetos Statement. Actúa

como un iterador que nos permite movernos a través de sus datos.

• SQLException: Esta clase maneja cualquier error que ocurra en una

aplicación de base de datos.

Los paquetes JDBC

Java.sql y javax.sql son los paquetes principales para JDBC. Ofrece las principales
clases para interactuar con sus fuentes de datos.

java.sql es una API para acceder y procesar los datos almacenados en una base de
datos, generalmente una base de datos relacional que usa Java. Se pueden instalar

Campus Impúlsate | [email protected]


diferentes controladores dinámicamente para el acceso de varias bases de datos,
utilizando un marco incorporado en esta API JDBC.

javax.sql es una API JDBC para el lado del servidor para acceder y procesar los datos
de las bases de datos, normalmente una base de datos relacional que usa Java. Es la
parte esencial para J2EE. Esta API proporciona funcionalidades como la agrupación de
conexiones, las transacciones distribuidas y los conjuntos de filas para las aplicaciones
empresariales. En esta API se proporciona una interfaz por nombre DataSource como
alternativa a DriverManager para establecer la conexión.

Sintáxis SQL

Structured Query Language (SQL) es un lenguaje estandarizado que le permite


realizar operaciones en una base de datos, tales como la creación de entradas, el
contenido de la lectura, actualización de contenidos, y eliminando las entradas.

SQL es compatible con casi cualquier base de datos que podamos utilizar, y permite
escribir código de base de datos independientemente de la base de datos subyacente.

A continuación, veremos una descripción general de SQL, que es un requisito previo


para comprender los conceptos de JDBC. Las operaciones sobre los datos de una base
de datos de una base de datos se clasifican en Crear, Read, Update y Delete (a menudo
referido como CRUD operaciones).

Crear base de datos

La sentencia CREATE DATABASE se usa para crear una nueva base de datos. La
sintaxis es la siguiente:

SQL> CREATE DATABASE DATABASE_NAME;

Ejemplo
La siguiente instrucción SQL crea una Base de datos llamada EMP:

SQL> CREATE DATABASE EMP;

Eliminar base de datos

La declaración DROP DATABASE se utiliza para eliminar una base de datos


existente. La sintaxis es la siguiente:

SQL> DROP DATABASE DATABASE_NAME;

Nota: Para crear o eliminar una base de datos, necesitamos tener privilegios de
administrador en su servidor de base de datos. Al eliminar una base de datos se
perderán todos los datos almacenados en la base de datos.

Crear tabla

Campus Impúlsate | [email protected]


La instrucción CREATE TABLE se usa para crear una nueva tabla. La sintaxis es la
siguiente:

SQL> CREATE TABLE table_name


(
column_name column_data_type,
column_name column_data_type,
column_name column_data_type
...
);

Ejemplo
La siguiente instrucción SQL crea una tabla llamada Empleados con cuatro columnas:

SQL> CREATE TABLE Employees (


id INT NOT NULL,
age INT NOT NULL,
first VARCHAR(255),
last VARCHAR(255),
PRIMARY KEY ( id )
);

Borrar tabla

La instrucción DROP TABLE se usa para eliminar una tabla existente. La sintaxis es
la siguiente:

SQL> DROP TABLE table_name;

Ejemplo
La siguiente instrucción SQL elimina una tabla llamada Empleados:

SQL> DROP TABLE Employees;

Insertar datos

La sintaxis de INSERT se muestra a continuación, donde column1, column2, etc.,


representa los datos nuevos que aparecerán en las columnas respectivas:

SQL> INSERT INTO table_name VALUES (column1, column2, ...);

Ejemplo
La siguiente instrucción SQL INSERT inserta una nueva fila en la base de datos de
Empleados creada anteriormente:

SQL> INSERT INTO Employees VALUES (100, 18, 'Zara', 'Ali');

Campus Impúlsate | [email protected]


Seleccionar datos

La instrucción SELECT se usa para recuperar datos de una base de datos. La


sintaxis es la siguiente:

SQL> SELECT column_name, column_name, ...


FROM table_name
WHERE conditions;

La cláusula WHERE puede usar operadores de comparación como =,! =, <,>, <=
Y> =, así como los operadores BETWEEN y LIKE.

Ejemplo
La siguiente instrucción SQL selecciona la edad, la primera y la última columna de la
tabla Empleados, donde la columna de identificación es 100.

SQL> SELECT first, last, age


FROM Employees
WHERE first LIKE '%Zara%';

La siguiente instrucción SQL selecciona la edad, la primera y la última columna de la


tabla Empleados, donde la primera columna contiene Zara :

SQL> SELECT first, last, age


FROM Employees
WHERE id = 100;

Actualizar datos

La instrucción UPDATE se usa para actualizar datos. La sintaxis es la siguiente:

SQL> UPDATE table_name


SET column_name = value, column_name = value, ...
WHERE conditions;

La cláusula WHERE puede usar operadores de comparación como =,! =, <,>, <=
Y> =, así como los operadores BETWEEN y LIKE.

Ejemplo
La siguiente instrucción SQL UPDATE cambia la columna de edad del empleado cuyo
ID es 100:

SQL> UPDATE Employees SET age=20 WHERE id=100;

Borrar datos

Campus Impúlsate | [email protected]


La declaración DELETE se utiliza para eliminar datos de tablas. La sintaxis es la
siguiente::

SQL> DELETE FROM table_name WHERE conditions;

La cláusula WHERE puede usar operadores de comparación como =,! =, <,>, <=
Y> =, así como los operadores BETWEEN y LIKE.

Ejemplo
La siguiente declaración SQL DELETE borra el registro del empleado cuyo ID es 100:

SQL> DELETE FROM Employees WHERE id=100;

API de Java Naming and Directory Interface (JNDI)

La Interfaz de Nombrado y Directorio Java (Java Naming and Directory Interface) es una
Interfaz de Programación de Aplicaciones (API) para servicios de directorio.

Esto permite a los clientes descubrir y buscar objetos y nombres a través de un nombre
y, como todas las APIs de Java que hacen de interfaz con sistemas host, es
independiente de la implementación subyacente.

Adicionalmente, especifica una interfaz de proveedor de servicio (SPI) que permite que
las implementaciones del servicio de directorio sean integradas en el framework. Las
implementaciones pueden hacer uso de un servidor, un fichero, o una base de datos; la
elección depende del vendedor.

Los servicios de Nombre y Directorio

Análogos a un operador telefónico

Si quieres llamar a alguien pero desconoces su número de teléfono, entonces puedes


llamar a un teléfono de información de tu compañía telefónica para buscar (look up) el
número de teléfono de la persona que quieres llamar. Le das al operador el nombre de
la persona a localizar y el operador busca el número de teléfono y te conecta a dicha
persona.

Entidad que realiza las siguientes tareas:

Asocia nombres con objetos:

a esto se le llama unión (binding) de nombres a Objetos

facilita la búsqueda de Objetos basados en nombres

Soportados por diferentes productos

NIS (Network Information service) en redes Solaris y Unix

NDS (Novell Directory Services) en redes Novell

Campus Impúlsate | [email protected]


ADSI (Active Directory Service Interface) en redes Microsoft

LDAP (Lightweight Directory Access Protocol) fue creado a principios de los años
noventa como protocolo de directorio estándar.

Hoy en día LDAP es el protocolo con más aceptación.

Los distribuidores NIS, NDS Y ADSI proporcionan interfaces de sus protocolos


propietarios para que LDAP se pueda comunicar con ellos.

Antes de que existiera JNDI, los desarrolladores Java tenían que programar
específicamente un servicio de directorios en una red concreta. Este hecho complicaba
bastante las cosas porque cada servicio de directorio de red tiene sus
propias APIs propietarias.

Esta imagen nos muestra cómo se interactuaba con estos diferentes servicios de
directorio sin JNDI

JNDI proporciona una API común a una variedad de servicios de directorios. Este API
está incluido como parte estándar de Java, del mismo modo que JDBC proporciona una
API estándar para las Bases de Datos Relacionales.

Esta imagen nos muestra cómo JNDI unifica el acceso a servicios de directorio de
redes heterogéneos:

Campus Impúlsate | [email protected]


Proveedores de servicios JNDI

En grandes Centros de Cálculo se suele disponer de un Ordenador que realiza las


labores de proveedor de servicios JNDI.

De esta forma todo el mundo que quiera acceder a una BDS particular solamente tiene
que comunicarse con el proveedor de servicios JNDI e indicarle el nombre de directorio
de la BDS en cuestión.

La ventaja de utilizar esta forma de acceder a una BDS es que ésta puede cambiar su
localización, es decir su dirección IP, e incluso también puede cambiar el nombre de la
BDS pero todos estos cambios son transparentes al usuario que quiere conectar con
dicha BDS.

Un proveedor de servicios JNDI es en definitiva un conjunto de Clases Java. Una de


estas Clases tiene que implementar la Interfaz DirectoryContext que a su vez hereda de
la Interfaz Context.

El proveedor de servicios JNDI necesita que el usuario que requiere un servicio


se autentifique a través de un nombre de usuario y una contraseña.

Cadenas de conexión

Las cadenas de conexión se establecen utilizando


DriverManager.getConnection().

// MySQL
Connection conexion = DriverManager.getConnection(
"jdbc:mysql://servidor:3306/database",
"usuario",
"password");

Campus Impúlsate | [email protected]


// Oracle
Connection conexion = DriverManager.getConnection(
"jdbc:oracle:thin:@servidor:1521:database",
"usuario",
"password");
// Access
Connection conexion = DriverManager.getConnection(
"jdbc:odbc:nombre_fuente_datos");
// PostgreSQL
Connection conexion = DriverManager.getConnection(
"jdbc:postgresql://servidor:5432/database",
"usuario",
"password");

Servidor representa el nombre o ip del servidor de base de datos y database es el


nombre de la base de datos a la que queremos conectarnos. El número de cuatro
cifras es el puerto en el que escucha nuestro servidor. Los valores por defecto para el
puerto en cada base de datos son los que aparecen en el código y podemos omitirlos
si son esos valores por defecto.

Tipos de conexión

Para conectarse a bases de datos individuales, JDBC necesita un driver específico


para cada una de ellas.

Hay cuatro tipos de drivers:

Tipo de Driver Descripción

Este es el driver que se incluye en la plataforma Java2.

Proporciona acceso a base de datos a través de uno o más


Puente JDBC-ODBC drivers ODBC, aprovechando todo lo que ya existe.

El rendimiento se resiente al tener que realizarse la


conversión de las transacciones de JDBC a ODBC.

Este driver realiza la comunicación directa con la libreria


que proporciona el fabricante de la base de datos.

Actualmente, sólo IBM y Oracle proporcionan este tipo de


Java / Binario
drivers para acceso a sus bases de datos.

WebLogic ofrece dirvers de este tipo para acceder a las


base de datos más populares: SQL Server, Sybase.

Realizado totalmente en Java, convierte directamente las


100% JAVA/
peticiones JDBC del cliente en peticiones de red contra el
Protocolo Nativo
servidor. Esta conversión se realiza en el cliente.

Campus Impúlsate | [email protected]


El driver convierte las llamadas JDBC directamente a
100% JAVA/ llamadas nativas hacia el sistema DBMS de que se trate.
Protocolo
independiente Esta conversión se realiza en el servidor, el cliente puede
usar un driver JDBC genérico.

Apertura y cierre de la conexión

Instalación del driver de base de datos.

Los requisitos iniciales son:

Disponer de la base de datos creada.

Adjuntar el fichero jar que nos suministre el proveedor para poder conectarnos a su base
de datos.

En la siguiente imagen adjuntamos el fichero jar a nuestro proyecto con las clases
necesarias para trabajar con una base de datos Oracle. Simplemente se añade en la
carpeta Libraries de nuestro proyecto, que como ya vimos el equivalente a classpath de
java.

Campus Impúlsate | [email protected]


El paso 1 será cargar el driver que suministra Oracle para poder conectarnos a su motor
de base de datos.

// Cargamos driver ORACLE

DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());

Una vez cargado el driver, podemos realizar la conexión.

Esta conexión se realiza mediante el método getConnection() de la clase


DriverManager.

Connection conn = DriverManager.getConnection


("jdbc:oracle:thin:@Servidor:1521:NombreBD","usuario", "password");

Métodos de la clase
connection

void clearWarnings()
Borra todos los warnings comunicados por este objeto
Connection

void close()
Cierra la conexión liberando todos los recursos que
estuviese utilizando.

Statement createStatement()
Crea una sentencia (representada por el objeto Statement)
que permitirá enviar comandos SQL a la base de datos.

SQLWarning getWarnings()
Devuelve el primer warning provocado por llamadas sobre
este objeto Connection.

boolean isClosed()
Comprueba si la conexión está cerrada.

boolean isReadOnly()
Comprueba si la conexión está en modo de sólo lectura.

void setReadOnly(boolean readOnly)


Pone esta conexión en modo sólo lectura.

Instalación de Oracle 11g Express Edition

1. Bajar el servidor de Base de de datos desde la siguiente


página: http://www.oracle.com/technetwork/products/express-
edition/downloads/index.html

Campus Impúlsate | [email protected]


Seguramente os pida que os registréis primero antes de permitiros bajar el software,
tenéis que hacerlo. La versión que os vais a bajar es para sistemas de 32 bits. Todavía
no hay edición de 64 bits para Windows de modo que si tenéis un Windows de 64bit
usar el ejecutable de 32bit debería funcionar. A la inversa no, es decir, un ejecutable de
64 bits no se puede ejecutar en un sistema operativo de 32 pero a la inversa si.

2. Descomprimir el rar bajado anteriormente e instalar. Los pasos que tenéis que
seguir son: pinchar en siguiente continuamente excepto en el caso en el que os pide
que introduzcáis un password. Este password será el pasword del administrador de
bases de datos.

3. Iniciar la BD. Para ello tenéis que ir a programas/Oracle Database 11g Express
edition/Start Database

4. IMPORTANTE: hay que cambiar el puerto del servidor web que viene con el
servidor de BD. Para ello abrís una consola de Windows cmd o directamente ir a
programas/ejecutar/cmd

En la consola escribís sqlplus y ejecutáis. Luego os pide un login y password teneis que
usar como login:system y password el que hayáis escogido durante la instalación y luego
ejecutáis la sentencia: exec dbms_xdb.sethttpport('7979'); y tras la ejecución
satisfactoria del comando cerráis la consola y reiniciais.

Es necesario cambiar este puerto ya que el servidor de aplicaciones que viene


instalado en netbeans también se lanza en el mismo puerto (8080). Tras reiniciar la
máquina hay que volver a iniciar el servidor de BD (ver punto 3).

5. Instalar el Cliente de la base de datos, para ello, tenéis que descargaros el


SQLDeveloper: http://www.oracle.com/technetwork/developer-tools/sql-
developer/downloads/index.html

6. Descomprimir el rar descargado y ya tenéis el programa listo para trabajar, no hace


falta instalar

7. Cuando arranquéis por primera vez el SQLDeveloper os va a pedir que le indiquéis


un ejecutable de java. Mediante el botón buscar, teneis que escoger el directorio de

Campus Impúlsate | [email protected]


instalación de la jdk de java y buscar el ejecutable “java”. Por ejemplo yo le indiqué la
siguiente ruta” C:\Program Files\Java\jdk1.7.0_25\bin\java” porque tengo instalada la
jdk 1.7 en archivos de programas/java, debemos tener en cuenta nuestra versión e
indicarla en la ruta.

8. Una vez iniciado el servidor de BD y el cliente, creamos una conexión al servidor


de BD. Para ello en el SQL Developer vamos a archivo/ Nuevo/Conexión a BD y se
abrirá la siguiente ventana:

Indicáis un nombre de conexión cualquiera, como login usáis: system, sin espacios y
como password, el pasword que le habréis indicado durante la instalación del servidor
de bases de datos.

9. Crear una base de datos nueva, para ello copiáis el siguiente contenido en el editor
de consultas de SQLDeveloper y pincháis en ejecutar script.

CREATE USER DB_TEST IDENTIFIED BY DB_TEST;

GRANT CREATE session TO DB_TEST;

GRANT CREATE table TO DB_TEST;

GRANT CREATE view TO DB_TEST;

GRANT CREATE PROCEDURE TO DB_TEST;

GRANT CREATE synonym TO DB_TEST;

GRANT UNLIMITED TABLESPACE TO DB_TEST;

Campus Impúlsate | [email protected]


Si os fijáis la primera sentencia del script crea un usuario DB_TEST, con password
DB_TEST.

Una aproximación muy sencilla de lo que supone una BD en Oracle es que las BD están
asociadas a usuarios por tanto al crear un usuario nuevo, en este caso DB_TEST,
hemos creado una BD.

10. Para acceder a la nueva BD creada cerráis la conexión anterior y abrís una nueva
conexión usando como login y password: DB_TEST

11. Creación de tablas en la BD. En este caso vamos a crear la tabla empleados para
el laboratorio 1. Recordad que este ejercico ya lo hemos hecho para una BD MS Acces
pues a partir de ahora se va a poder hacer con una BD Oracle.

Para crear la BD copiamos el siguiente contenido en el editor de consultas sql de la


nueva conexión DB_TEST y ejecutamos el script

CREATE TABLE EMP (

ID number primary key,

NAME VARCHAR2(100),

ENAME VARCHAR2(100),

JOB VARCHAR2(100),

Campus Impúlsate | [email protected]


SAL VARCHAR2(100),

DEPTNO VARCHAR2(100)

);

INSERT INTO EMP (ID, NAME, ENAME, JOB,SAL,DEPTNO)

VALUES (1, 'Antonio','Rodriguez Lopez', 'arquitecto','50000', 'arquitectura');

INSERT INTO EMP (ID, NAME, ENAME, JOB,SAL,DEPTNO)

VALUES (2, 'Jose', 'Lopez Fernandez', 'aparejador','40000', 'arquitectura');

INSERT INTO EMP (ID, NAME, ENAME, JOB,SAL,DEPTNO)

VALUES (3, 'Miguel','Fernandez Perez', 'aparejador','40000', 'arquitectura');

INSERT INTO EMP (ID, NAME, ENAME, JOB,SAL,DEPTNO)

VALUES (4, 'Rodrigo','Gonzalez Gonzalez ', 'ingeniero','50000', 'procesos');

INSERT INTO EMP (ID, NAME, ENAME, JOB,SAL,DEPTNO)

VALUES (5, 'Angel','Gonzalez Rodriguez', 'ingeniero-tecnico','40000', 'procesos');

commit;

CREATE TABLE DEPT (

DEPTNO number primary key,

DNAME VARCHAR2(100),

LOC VARCHAR2(100)

);

INSERT INTO DEPT VALUES (10, 'arquitectura','granada');

INSERT INTO DEPT VALUES (20, 'procesos', 'granada');

INSERT INTO DEPT VALUES (30, 'sistemas','sevilla');

INSERT INTO DEPT VALUES (40, 'analisis','malaga');

commit;

Campus Impúlsate | [email protected]


12. Conexión Java – Oracle usando jdbc. Para poder conectaros desde
una aplicación java a la BD usando JDBC, tenéis que descargaros el driver JDBC de
Oracle y que podéis encontrar en esta
página http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-
090769.html y os descargáis el jar “ojdbc6.jar” que es el driver para la JDK 1.6 y
superiores. Si alguien tiene la JDK 1.5 tiene que descargarse el jar “ojdbc5.jar”.

Para conectaros mediante JDBC tenéis que usar las sentencias

DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());

Connection conn =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE","DB_TEST",
"DB_TEST");

Campus Impúlsate | [email protected]


Ejecución de sentencias

SQL es un lenguaje de acceso a las bases de datos que ofrece gran diversidad de
operaciones aprovechando la potencia y flexibilidad de los sistemas relacionales.

Es un lenguaje de alto nivel o de no procedimiento, que favorecido por su base teórica y


su orientación a la manipulación de conjuntos de registros y no individuales, ofrece una
alta productividad en codificación y la orientación a objetos.

Un programa en cualquier lenguaje se puede concebir como un string de caracteres


escogidos de algún conjunto o alfabeto de caracteres. Las reglas que determinan si
un string es un programa válido o no, constituyen la sintaxis de un lenguaje.
Posteriormente, se estudiarán ciertas notaciones denominadas expresiones regulares y
gramáticas libres de contexto, muy usadas no sólo para especificar las sintaxis de los
lenguajes de programación sino también para contribuir en la construcción de sus
compiladores.

En SQL, el Lenguaje de Definición de Datos o DDL sirve para definir estructuras de


almacenamiento, y por tanto para crear esquemas conceptuales.

El compilador DDL convierte las instrucciones DDL en una serie de tablas que
contienen los metadatos o datos acerca de los datos. El resultado de compilar todas las
instrucciones DDL se almacena en el Diccionario de Datos.

Por otro lado, DML es definido como el idioma facilitado por los sistemas gestores de
bases de datos, el cual permite que los usuarios de la base de datos puedan realizar
tareas de modificación o consulta de datos alojados en la base de datos mediante un
sistema gestor de base de datos.

3.3.1 Sentencias de creación: CREATE

La sentencia CREATE, es utilizada en el lenguaje de base de datos para crear, base


de datos, tablas, vistas, procedimientos y triggers. A continuación veremos la sintaxis
para crear cada uno de los nombrados.

Bases de datos.

CREATE DATABASE nombre_de_la_BD;

Campus Impúlsate | [email protected]


Hay que tener en cuenta que en Unix los nombres de las bases de datos son case
sensitive. Esto también se aplica a los nombres de tablas. En Windows no existe esta
restricción.

Al crear una base de datos, ésta no queda seleccionada por defecto como la base de
datos que se va a usar, debe hacerse explícitamente mediante:

USE nombre_de_la_BD

Tablas

Con la sentencia CREATE TABLE introducimos la definición de una tabla en


el catálogo de la base de datos, le asignamos un espacio inicial y le asociamos las
restricciones de integridad que sean oportunas

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name

[(create_definition,...)]

[table_options] [select_statement]

CREATE TABLE crea una tabla con el nombre dado. Debe tener el permiso CREATE
para la tabla.

Por defecto, la tabla se crea en la base de datos actual. Ocurre un error si la tabla existe,
si no hay base de datos actual o si la base de datos no existe.

SQL incorpora una serie de tipos de datos estándar para de la definición de


los dominios de las columnas de una tabla. Los de uso más común se muestran en la
tabla siguiente.

Tipo de dato Descripción

INT o INTEGER o Enteros con signo (su rango depende de la implementación


NUMERIC del sistema)

REAL o FLOAT Datos numéricos en como flotante

CHAR(n) Cadena de longitud fija n

VARCHAR(n) Cadena de longitud variable de hasta n caracteres

Campus Impúlsate | [email protected]


VARCHAR2(n) De mínimo 1 carácter y máximo 4000. Otra implementación
de cadena más eficiente (específico de Oracle)

NUMBER(p,s) Número con precisión p y escala s, donde precisión indica el


número de dígitos, y escala el número de cifras decimales

LONG Cadena de caracteres de longitud variable de hasta 2


gigabytes (específico de Oracle)

LONG RAW (size) Cadena de datos binarios de longitud variable de hasta 2


gigabytes (específico de Oracle)

DATA o TIME o Fecha


TIMESTAMP

Vistas

CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]

VIEW nombre_vista [(columnas)]

AS sentencia_select

[WITH [CASCADED | LOCAL] CHECK OPTION]

Esta sentencia crea una vista nueva o reemplaza una existente si se incluye la cláusula
OR REPLACE. La sentencia_select es una sentencia SELECT que proporciona la
definición de la vista. Puede estar dirigida a tablas de la base o a otras vistas.

Se requiere que posea el permiso CREATE VIEW para la vista, y algún privilegio en
cada columna seleccionada por la sentencia SELECT. Para columnas incluidas en otra
parte de la sentencia SELECT debe poseer el privilegio SELECT. Si está presente la
cláusula OR REPLACE, también deberá tenerse el privilegio DELETE para la vista.

Toda vista pertenece a una base de datos. Por defecto, las vistas se crean en la base
de datos actual. Pera crear una vista en una base de datos específica, indíquela con
base_de_datos.nombre_vista al momento de crearla.

CREATE VIEW test.v AS SELECT * FROM t;

Disparadores o Triggers

CREATE TRIGGER nombre_disp momento_disp evento_disp

ON nombre_tabla FOR EACH ROW sentencia_disp

Un disparador es un objeto con nombre en una base de datos que se asocia con una
tabla, y se activa cuando ocurre un evento en particular para esa tabla.

El disparador queda asociado a la tabla nombre_tabla. Esta debe ser una tabla
permanente, no puede ser una tabla TEMPORARY ni una vista.

Campus Impúlsate | [email protected]


Procedimientos

CREATE {OR REPLACE} PROCEDURE nombre_proc (param1 [IN | OUT | IN OUT]


tipo,...)

IS

Declaración de variables locales

BEGIN

Instrucciones de ejecución

[EXCEPTION]

Instrucciones de excepción

END;

Un procedimiento [almacenado] es un subprograma que ejecuta una acción específica


y que no devuelve ningún valor por sí mismo, como sucede con las funciones.

3.3.2 Sentencias de modificación: ALTER

La sentencia ALTER, es utilizada en el lenguaje de base de datos para modificar datos,


pueden ser tanto como una base de datos, una tabla, una vista, un procedimiento y
un tirgger. A continuación veremos la sintaxis para modificar cada uno de los
nombrados.

Bases de datos

ALTER {DATABASE | SCHEMA} [db_name]

alter_specification [, alter_specification]

[DEFAULT] CHARACTER SET charset_name

| [DEFAULT] COLLATE collation_name

ALTER DATABASE nos da la opción para modificar las características generales de


una base de datos. Estas características se guardan en el fichero db.opt en el directorio

Campus Impúlsate | [email protected]


de la base de datos. Para usar ALTER DATABASE, es necesario tener el permiso
ALTER en la base de datos.

Tablas

ALTER [IGNORE] TABLE tbl_name

alter_specification [, alter_specification] ...

alter_specification:

ADD [COLUMN] column_definition [FIRST AFTER col_name ]

ALTER TABLE le permite cambiar la estructura de una tabla existente. Por ejemplo,
puede añadir o borrar columnas, crear o destruir índices, cambiar el tipo de columnas
existentes, o renombrar columnas o la misma tabla. Puede cambiar el comentario de la
tabla y su tipo.

Vistas

ALTER [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]

VIEW nombre_vista [(columnas)]

AS sentencia_select

[WITH [CASCADED | LOCAL] CHECK OPTION]

Esta sentencia modifica la definición de una vista existente. La sintaxis es semejante a


la empleada en CREATE VIEW. Se requiere que posea los permisos CREATE VIEW y
DELETE para la vista, y algún privilegio en cada columna seleccionada por la sentencia
SELECT.

Disparadores o Triggers

alter trigger nombre_disparador opcion_a_modificar

La sentencia alter trigger, modifica cualquier opción especificada en la creación de


este.

Por ejemplo, la sintaxis para deshabilitar un trigger sería:

alter trigger NOMBREDISPARADOR disable;

Procedimientos.

ALTER {PROCEDURE | FUNCTION} sp_name [characteristic ...]

characteristic:

{}

Campus Impúlsate | [email protected]


| SQL SECURITY { DEFINER | INVOKER }

| COMMENT 'string'

Este comando puede usarse para cambiar las características de un procedimiento o


función almacenada.

3.3.3 Sentencias de borrado: DROP, TRUNCATE

La sentencia DROP, es utilizada en el lenguaje de base de datos para borrar base de


datos, tablas, vistas, procedimientos y triggers. A continuación veremos la sintaxis para
borrar cada uno de los nombrados.

Bases de datos.

DROP DATABASE [IF EXISTS] nombre_db

DROP DATABASE borrar todas las tablas en la base de datos y borrar la base de datos.
Para usarDROP DATABASE, es necesario tener asignado el permiso DROP en la base
de datos. IF EXISTS se usa para evitar un error si la base de datos no existe.

Tablas.

DROP [TEMPORARY] TABLE [IF EXISTS]

tbl_name [, tbl_name] ...

[RESTRICT | CASCADE]

DROP TABLE borra una o más tablas. Debe tener el permiso DROP para cada tabla.
Todos los datos de la definición de tabla son borrados, así que tenga cuidado con este
comando.

Use IF EXISTS para evitar un error para tablas que no existan. Un NOTE se genera
para cada tabla no existente cuando se usa IF EXISTS.

RESTRICT y CASCADE se permiten para hacer la portabilidad más fácil. De momento,


no hacen nada.

Vistas

DROP VIEW [IF EXISTS]

nombre_vista [, nombre_vista] ...

[RESTRICT | CASCADE]

DROP VIEW elimina una o más vistas de la base de datos. Se debe poseer el privilegio
DROP en cada vista a eliminar.

Campus Impúlsate | [email protected]


La cláusula IF EXISTS se emplea para evitar que ocurra un error por intentar eliminar
una vista inexistente. Cuando se utiliza esta cláusula, se genera una NOTE por cada
vista inexistente.

RESTRICT y CASCADE son ignoradas.

Disparadores o Triggers.

DROP TRIGGER nombre_disp

La sentencia drop trigger elimina un disparador.

Procedimientos.

DROP PROCEDURE [IF EXISTS] nombre_procedimiento

Este comando se usa para borrar un procedimiento. Es necesario disponer del permiso
ALTER. Este permiso se le asigna de forma automática al creador de la rutina.

3.3.4 Sentencias de consulta: SELECT

Las consultas de selección, las utilizamos para que nuestro motor de datos nos
devuelva información de la base de datos. Los datos devueltos tendrán forma de
conjunto de registro y se podrán almacenar en un objeto recordset. El conjunto de
registros será modificable.

Dentro de las consultas de selección, podemos diferenciar entre:

• Consultas básicas.

• Consultas con predicado, el predicado lo incluiremos entre la cláusula y el

primer nombre del campo a recuperar. Los predicados disponibles son:

o ALL, nos devuelve todos los campos de la tabla.

o TOP, nos devuelve un determinado número de registros

o DISTINCT, omite los registros cuyos campos sean coincidentes

totalmente

o DISTINCTROW, omite los registros duplicados

SELECT [{,}]

FROM

[WHERE ];

Campus Impúlsate | [email protected]


• La cláusula inicial de la sentencia SELECT contiene las columnas que

queremos mostrar

• La cláusula FROM indica la tabla sobre la que queremos consultar

• La cláusula opcional WHERE impone una condición booleana que deben

cumplir las tuplas para ser recuperadas

Para devolver el resultado de la consulta ordenado, SQL incorpora la cláusula


adicional ORDER BY, que permite establecer los criterios de ordenación. Esta cláusula
es opcional y se escribe a continuación de la cláusula WEHRE, con la
siguiente sintaxis:

ORDER BY id_columna [ASC|DESC] [{,id_columna [ASC|DESC]}]

3.3.5 Sentencias de inserción: INSERT

Para insertar datos en una tabla, SQL dispone de la sentencia INSERT. La sintaxis de
la sentencia INSERT es la siguiente:

Un ejemplo de INSERT sería:

INSERT INTO tienda (artículo,vendedor,precio) VALUES(1,’Pepito’,12);

3.3.6 Sentencias de modificación: UPDATE

Para la modificación o actualización de filas de una tabla se utiliza


la sentencia UPDATE de SQL. Con UPDATE podremos actualizar los datos de una
tabla o de varias tablas a la vez.

La sintaxis de UPDATE para una tabla es:

Campus Impúlsate | [email protected]


La sintaxis para múltiples tablas es:

Un ejemplo de utilización de UPDATE para la tabla “Tienda” si se quisiera incrementar


el precio de los artículos un 3% sería:

UPDATE tienda SET precio=precio*1.03;

3.3.7 Sentencias de borrado de datos: DELETE

Para borrar de datos de una tabla se realiza con la sentencia DELETE. Se puede hacer
la eliminación de los datos de una tabla o de múltiples tablas:

La sintaxis para una tabla es la siguiente:

La sintaxis para múltiples tablas es:

Por ejemplo, si se quisieran eliminar los registros de la tabla “Tienda” a cuando el artículo
sea el 1, se haría:

DELETE FROM tienda WHERE articulo=1;

3.3.8 Otros elementos de manipulación de datos

Además de las sentencias que se acaban de ver para llevar a cabo la manipulación de
datos existen otras no tan habituales.

Campus Impúlsate | [email protected]


DO.

Es un tipo de sentencia que se utiliza para ejecutar un bloque de código anónimo,


aunque no es una sentencia de SQL estándar.

Veamos un ejemplo en postgreSQL para darle todos los permisos al rol webuser sobre
todas las vistas del esquema public:

DO $$DECLARE r record;

BEGIN

FOR r IN SELECT table_schema, table_name FROM information_schema.tables

WHERE table_type = 'VIEW' AND table_schema = 'public'

LOOP

EXECUTE 'GRANT ALL ON ' || quote_ident(r.table_schema) || '.' ||


quote_ident(r.table_name) || ' TO webuser';

END LOOP;

END$$;

REPLACE.

Con esta función se puede reemplazar un texto por otro dentro de una consulta sobre
una cadena de texto,

Por ejemplo, en SQL Server, si hiciéramos la consulta:

SELECT Replace(‘Hola Mundo’, ‘Mundo’, ‘a todos!’);

La salida será: ‘Hola a todos!’

Campus Impúlsate | [email protected]


Otros elementos.

Existen otras muchas sentencias, para llevar a cabo la manipulación de datos, aunque
la mayoría de ellas no son estándar.

Por ejemplo:

- DISCARD: Se utiliza para descartar el estado de la sesión, y libera los recursos


internos asociados a la sesión de la base de datos. Estos recursos se liberan
normalmente al final de la sesión si no se especifica nada antes. Así, por ejemplo se
podrían borrar las tablas temporales creadas en la sesión, los planes para las consultas
en la memoria caché, etc.

- DECLARE: Sirve para definir cursores. Los cursores se pueden usan para recuperar
un número relativamente pequeño de filas de una consulta que devuelva un número
elevado de filas.

3.3.9 Operadores de conjunto: UNION, INTERSECT y MINUS

El álgebra relacional dispone de una serie de operadores de conjunto (unión,


intersección y diferencia) que permiten operar sobre los resultados de dos consultas y
obtener el resultado equivalente de aplicar la operación correspondiente a la teoría de
conjuntos.

SQL también incorpora operadores equivalentes a dichas operaciones, son UNION,


INTERSECT y MINUS. Para poder aplicarlos sobre dos consultas, los resultados de
ambas han de ser compatibles desde el punto de vista estructural (mismo número de
columnas y concordancia o compatibilidad de tipos).

3.3.11 Subconsultas

Una subconsulta es un comando SELECT dentro de otro comando.

SELECT * FROM ti WHERE columnl = (SELECT columnl FROM t2);

En este ejemplo, SELECT * FROM ti ... es la consulta externa (o comando externo), y


(SELECT columnl FROM t2) es la subconsulta. Decimos que la subconsulta está
anidada dentro de la consulta exterior, y de hecho, es posible anidar subconsultas dentro
de otras subconsultas hasta una profundidad considerable. Una subconsulta debe
siempre aparecer entre paréntesis.

Las principales ventajas de subconsultas son:

Permiten consultas estructuradas de forma que es posible aislar cada parte de un


comando.

Proporcionan un modo alternativo de realizar operaciones que de otro modo


necesitarían joins y uniones complejos.

Son, en la opinión de mucha gente, leíbles. De hecho, fue la innovación de


las subconsultas lo que dio a la gente la idea original de llamar a SQL “Structured
Query Language.”

Campus Impúlsate | [email protected]


Una subconsulta puede retornar un escalar (un valor único), un registro, una columna
o una tabla (uno o más registros de una o más columnas). Éstas se llaman consultas de
escalar, columna, registro y tabla. Las subconsultas que retornan una clase particular
de resultado a menudo pueden usarse sólo en ciertos contextos, como se describe en
las siguientes secciones.

Hay pocas restricciones sobre los tipos de comandos en que pueden usarse las
subconsultas. Una subconsulta puede contener cualquiera de las palabras claves o
cláusulas que puede contener un SELECT ordinario: DISTINCT, GROUP BY, ORDER
BY, LIMIT, joins, trucos de índices, constructores UNION, comentarios, funciones, y así.

Una restricción es que el comando exterior de una subconsulta debe ser: SELECT,
INSERT, UPDATE, DELETE, SET, o DO. Otra restricción es que actualmente no
puede modificar una tabla y seleccionar de la misma tabla en la subconsulta. Esto se
aplica a comandos tales como DELETE, INSERT, REPLACE, y UPDATE.

3.3.12 Manipulación del diccionario de datos

El diccionario de datos contiene información relevante o metadatos sobre los datos que
se almacenan en la base de datos, y por tanto estos datos también se almacenarán
como el resto de datos, en la propia base de datos, pero sólo el sistema o
un usuario concreto podrá mantener estos datos. El SGBD podrá gestionar los recursos
haciendo uso de esta información. Esta información sobre los datos definirá la estructura
de los datos, el tipo de datos que se van a usar, las restricciones que van a tener, índices
para un acceso más rápido, etc.

El diccionario de datos se crea a la vez que se crea la base de datos y es mantenido o


actualizado por el SGBD cada vez que hay una modificación en la estructura de la base
de datos.

Como veíamos antes, el diccionario de datos está compuesto por datos debe
almacenarse en la propia base de datos, y por tanto habrá una serie de tablas y vistas
que conformarán la estructura del diccionario de datos. Estas tablas estarán dedicadas
exclusivamente a proporcionar información sobre los objetos de la base de datos. Suele
haber una tabla en el diccionario de datos para cada tipo de objeto posible: tablas, vistas,
usuarios, roles, secuencias, disparadores, etc.

Campus Impúlsate | [email protected]


Especificación de restricciones de integridad

Si no se gestiona adecuadamente una base de datos podría


haber registros duplicados, actualizaciones perdidas y datos inconsistentes, y por tanto
no habría integridad en los datos.

En general, podemos decir que la integridad de los datos se refiere a que


los datos deben ser datos correctos y estar completos, englobando por supuesto las
características de los datos como: definiciones, fechas, reglas que les afecten, etc.

Los SGBD deben encargarse de mantener la integridad de los datos con respecto a las
definiciones y restricciones que se hayan definido en la base de datos, pero la integridad
de los datos también puede controlarse a la hora de introducir los datos, por ejemplo
cuando se lleva a cabo la validación de un campo a través de un formulario, es decir, si
se introducen letras en un campo dedicado a cantidades numéricas, esto estaría
violando la integridad de los datos ya que no sería un dato correcto y se podría gestionar
mediante una validación del tipo de dato o del rango donde debe estar incluido, etc.

A grandes rasgos podemos clasificar las restricciones que garantizan la integridad de


los datos en dos grandes grupos: las condiciones que impone el usuario (como por
ejemplo, podría imponer que en una tabla de salarios el campo dedicado al sueldo no
fuera inferior al salario mínimo), y las condiciones o restricciones que son propias del
modelo, en este caso el modelo relacional.

Las restricciones de integridad que imponga el usuario se mantendrán para una base
de datos concreta, pero no para cualquier base de datos que se cree, sin embargo, las
restricciones del modelo son unas restricciones implícitas que se van a cumplir para
cualquier base de datos que se cree siguiendo dicho modelo. Entre las reglas de
integridad del modelo podemos destacar:

-Regla de unicidad de clave primaria, es decir, la clave primaria que se elija para una
tabla debe ser única para cada registro, por tanto, no puede haber valores repetidos en
el conjunto de valores de la clave primaria.

- Regla de entidad de la clave primaria, que quiere decir que el valor nulo no puede
ser un valor válido para la clave primaria.

- Regla de integridad referencial, que quiere decir que los valores que tomen las
claves externas tienen que ser valores que existan en la clave primaria a la que hacen
referencia o ser nulos.

- Regla de integridad de dominio, que a grandes rasgos se refiere a la definición del


conjunto de posibles valores que puede tomar un determinado campo de una tabla y los
operadores que pueden operar con dichos valores. Esto determinará la integridad del
dominio del campo.

Campus Impúlsate | [email protected]


Además, hay otra serie de restricciones importantes como la del borrado, para que no
se puedan eliminar filas de la tabla que son referenciadas por otras, la actualización en
cascada de las filas que hacen referencia a una fila actualizada, etc.

A través del objeto Connection, que representa una conexión física con la base de
datos, podemos crear y lanzar sentencias SQL.

Para ello se usará el método createStatement() el cual devolverá un objeto de tipo


Statement.

Este objeto Statement contendrá el resultado de la ejecución de la consulta, según la


consulta, serán las filas seleccionadas o bien el número de filas afectadas por la
consulta.

Statement sentencia=conexion.createStatement();

Sobre el objeto Statement podemos usar los siguientes métodos:

Métodos de la clase
Statement

void cancel()
Cancela este objeto Statement si el DBMS y el driver
soportan el abortar sentencias SQL.

void clearWarnings()
Borra todos los warnings comunicados por este objeto
Statement.

void close()
Cierra este objeto Statement y libera todos los recursos que
estaba usando.

Campus Impúlsate | [email protected]


boolean execute(String sql)
Ejecuta una sentencia SQL que puede retornar múltiples
resultados.

ResultSet executeQuery(String sql)


Ejecuta una sentencia SQL que devuelve un único
ResultSet. Por ejemplo, un SELECT.

int executeUpdate(String sql)


Ejecuta una sentencia SQL de tipo SQL INSERT, UPDATE
o DELETE.

Connection getConnection()
JDBC 2.0 Devuelve el objeto Connection que produjo este
objeto Statement.

int getMaxFieldSize()
Devuelve el número máximo de bytes permitidos en el valor
de cualquier columna.

int getMaxRows()
Devuelve el número máximo de registros que puede
contener un ResultSet.

boolean getMoreResults()
Se mueve al siguiente registro del objeto Statement.

int getQueryTimeout()
Devuelve el número de milisegundos que esperará el driver
a que una sentencia SQL se ejecute.

ResultSet getResultSet()
Devuelve el resultado actual como un objeto ResultSet.

SQLWarning getWarnings()
Devuelve el primer warning comunicado en la llamadas
sobre este objeto Statement.

void setCursorName(String name)


Define el nombre del cursor que será usado por los
métodos execute de los objetos Statement siguientes.

void setMaxFieldSize(int max)


Pone el número máximo de bytes para una columna.

void setMaxRows(int max)


Pone el número máximo de registros que un ResultSet
puede contener.

void setQueryTimeout(int seconds)


Pone el número de segundos que esperará el driver a que
una sentencia se ejecute.

Campus Impúlsate | [email protected]


Ejecución de consultas de selección

Según lo que hemos visto, el código de lanzamiento de una consulta de selección será
el siguiente:

DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection cn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE",
"SYSTEM", "12345");
Statement sentencia =
cn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_R
EAD_ONLY);
ResultSet rs = sentencia.executeQuery("SELECT DISTINCT JOB FROM EMP");

Este método retorna un ResultSet con los datos resultado de la consulta.

También se puede utilizar el método execute(), que sirve para todas las consultas.
Simplemente retorna verdadero si se ha retornado un objeto ResultSet y falso si se ha
retornado un entero o nada.

El usuario necesitará los permisos necesarios sobre la base de datos.

En el siguiente apartado veremos el ejemplo desarrollado.

Ejemplo de aplicación web que recupere información de una base de datos

Crear un sitio web para poder visualizar información de las distribuidoras de un cine.

Tabla DISTRIBUIDORAS en Oracle

CREATE TABLE DISTRIBUIDORAS(DISTRIBUIDORA varchar2(40),IMAGEN


varchar2(20),INTERNET varchar2(35));

INSERT INTO DISTRIBUIDORAS VALUES('20 th Centyry


Fox','20century.jpg','http://www.fox.es/');

INSERT INTO DISTRIBUIDORAS VALUES('Aurum','aurum.gif','http://www.aurum.es/');

INSERT INTO DISTRIBUIDORAS VALUES('Columbia


Tristar','columbia.jpg','http://www.columbia-tristar.es/');

INSERT INTO DISTRIBUIDORAS


VALUES('Filmax','filmax.gif','http://www.filmax.com/');

INSERT INTO DISTRIBUIDORAS VALUES('Lauren


Films','laurenfilmx.gif','http://www.laurenfilm.es/');

INSERT INTO DISTRIBUIDORAS VALUES('Lola


Films','lolafilms.gif','http://www.lolafilms.com/');

INSERT INTO DISTRIBUIDORAS VALUES('MGM','mgm.jpg','http://www.mgm.com/');

Campus Impúlsate | [email protected]


INSERT INTO DISTRIBUIDORAS
VALUES('Miramax','miramax.jpg','http://www.miramax.com/');

INSERT INTO DISTRIBUIDORAS VALUES('New Line


Cinema','newlinecinema.jpg','http://www.newline.com/');

INSERT INTO DISTRIBUIDORAS VALUES('Tri-


Pictures','tripictures.gif','http://www.tripictures.com/');

INSERT INTO DISTRIBUIDORAS VALUES('UIP - Paramount,Universal y


Dreamworks','paramount.jpg','http://www.uip.es/');

INSERT INTO DISTRIBUIDORAS VALUES('Walt


Disney','waltdisney.jpg','http://www.disney.com/');

INSERT INTO DISTRIBUIDORAS VALUES('Warner


Bross','warner.gif','http://www.warnerbros.com/');

commit;

La página Distribuidoras.jsp debe cargar los datos de los tres campos de la tabla
distribuidoras:

Mostrar en una etiqueta img la imagen de la distribuidora.

Cargar en un hipervínculo el nombre de la distribuidora.

Al pulsar sobre la distribuidora debemos redirigir al usuario al sitio web de la


distribuidora.

Campus Impúlsate | [email protected]


Código JSP

<%@page language = "java" import="java.sql.*" %>

<% ResultSet rs; //Para los resultados de la consulta%>

<html>

<head>

<title>PRINCIPALES DISTRIBUIDORAS</title>

<link Rel="stylesheet" HRef="ESTILOS\estilo.css" Type="text/css">

</head>

<body>

<center>

<b class=titulo>PRINCIPALES DISTRIBUIDORAS</b>

</center>

<BR>

<table border="0" align=center cellspacing="10" cellpadding="4" width=400 class=gris>

Campus Impúlsate | [email protected]


<%-- Aqui la lista creada en un bucle--%>

<%

DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());

Connection conexion = DriverManager.getConnection


("jdbc:oracle:thin:@localhost:1521:XE","SYSTEM","12345");

Statement sentencia=conexion.createStatement();

rs=sentencia.executeQuery("SELECT internet,distribuidora,imagen from


distribuidoras");

int par=1; //Para controlar que muestre dos por fila

while(rs.next()){

String direccion=rs.getString(1);

String nombre=rs.getString(2);

String imagen=rs.getString(3);

if(par%2!=0){

out.println("<tr>");

String enlazar= "<a href="+direccion +" TARGET=_blank class=mediano>";

out.println("<TD><table border=0 cellpadding=4 width=180;><tr>");

out.println("<tD width=30>"+enlazar+"<img
src=IMAGENES\\DISTRIBUIDORAS\\"+imagen+" alt=\""+nombre+"\" border=0
width=60 height=42></a></td>");

out.println("<td align=left>"+enlazar+nombre+"</a></td></tr></table></TD>");

if(par%2==0){

out.println("</tr>");

par++;

if(par%2==0){

Campus Impúlsate | [email protected]


out.println("</tr>");

%>

</table>

</body>

</html>

Manejo de conjuntos de registros

Para recuperar información de la base de datos se recurre al método executeQuery(),


el cual devuelve un objeto de tipo ResultSet.

Un ResultSet es una clase java similar a una lista que contiene el resultado de la
consulta. Cada elemento de la lista es uno de los registros de la base de datos. En
realidad, un ResultSet no contiene todos los datos de la consulta, sino que los va
obteniendo de la base de datos según se van pidiendo. De esta forma el método
executeQuery() tarda muy poco tiempo, pero en cambio recorrer los elementos del
ResultSet ya no es tan rápido. Así evitamos que una consulta que retorne muchos datos
tarde demasiado tiempo y ocupe demasiada memoria del programa java.

ResultSet resultado=sentencia.executeQuery("SELECT * FROM tabla");

while(resultado.next()){

String titulo=resultado.getString("TITULO");

String autor=resultado.getString("AUTOR");

int precio=resultado.getInt("Precio");

Date publicacion=resultado.getDate("PUBLICACION");

System.out.println(....imprimir campos...");

Como se puede ver en los métodos de abajo, cada getxxx tiene dos posibilidades: dar
el nombre de la columna como un String o dar un índice que hace referencia al campo
en concreto (el índice comienza en 1 y se refiere al ResultSet que obtenemos de la
consulta y no a la base de datos completa).

Campus Impúlsate | [email protected]


Los métodos que podemos usar sobre el objeto ResultSet son:

Métodos de
ResultSet

boolean absolute(int row)


JDBC 2.0 Permite situarnos en un registro en concreto.

void afterLast()
JDBC 2.0 Permite situarnos después del último registro.

void beforeFirst()
JDBC 2.0 Permite situarnos antes del primer registro.

void close()
Cierra el objeto ResultSet y se liberan los recursos que estaba
usando.

void deleteRow()
JDBC 2.0 Borra el registro del ResultSet en el que nos
encontramos actualmente.Deletes the current row from the result
set and the underlying database.

boolean first()
JDBC 2.0 Nos colocamos en el primer registro.

BigDecimal getBigDecimal(int columnIndex)


JDBC 2.0 Obtiene el valor de una columna del registro actual
como un java.math.BigDecimal con precisión completa.

BigDecimal getBigDecimal(String columnName)


JDBC 2.0 Obtiene el valor de una columna del registro actual
como un java.math.BigDecimal con precisión completa.

InputStream getBinaryStream(int columnIndex)


Obtiene el valor de una columna como un stream de bytes.

InputStream getBinaryStream(String columnName)


Obtiene el valor de una columna como un stream de bytes.

boolean getBoolean(int columnIndex)


Obtiene el valor de una columna como un boolean.

boolean getBoolean(String columnName)


Obtiene el valor de una columna como un boolean.

byte getByte(int columnIndex)


Obtiene el valor de una columna como un byte.

byte getByte(String columnName)


Obtiene el valor de una columna como un byte.

Campus Impúlsate | [email protected]


byte[] getBytes(int columnIndex)
Obtiene el valor de una columna como un array de bytes.

byte[] getBytes(String columnName)


Obtiene el valor de una columna como un array de bytes.

Reader getCharacterStream(int columnIndex)


JDBC 2.0 Obtiene el valor de una columna como un Reader.

Reader getCharacterStream(String columnName)


JDBC 2.0 Obtiene el valor de una columna como un Reader.

String getCursorName()
Obtiene el nombre del cursor SQL usado por este ResultSet.

Date getDate(int columnIndex)


Obtiene el valor de una columna como un objeto java.sql.Date.

Date getDate(int columnIndex, Calendar cal)


JDBC 2.0 Obtiene el valor de una columna como un objeto
java.sql.Date.

Date getDate(String columnName)


Obtiene el valor de una columna como un objeto java.sql.Date.

Date getDate(String columnName, Calendar cal)


Obtiene el valor de una columna como un objeto java.sql.Date.

double getDouble(int columnIndex)


Obtiene el valor de una columna como un double.

double getDouble(String columnName)


Obtiene el valor de una columna como un double.

float getFloat(int columnIndex)


Obtiene el valor de una columna como un float.

float getFloat(String columnName)


Obtiene el valor de una columna como un float.

int getInt(int columnIndex)


Obtiene el valor de una columna como un int.

int getInt(String columnName)


Obtiene el valor de una columna como un int.

long getLong(int columnIndex)


Obtiene el valor de una columna como un long.

long getLong(String columnName)


Obtiene el valor de una columna como un long.

Campus Impúlsate | [email protected]


Object getObject(int columnIndex)
Obtiene el valor de una columna como un object.

Object getObject(String columnName)


Obtiene el valor de una columna como un object.

short getShort(int columnIndex)


Obtiene el valor de una columna como un short.

short getShort(String columnName)


Obtiene el valor de una columna como un short.

Statement getStatement()
JDBC 2.0 Devuelve el objeto Statement que produjo este objeto
ResultSet.

String getString(int columnIndex)


Obtiene el valor de una columna como un String.

String getString(String columnName)


Obtiene el valor de una columna como un String.

Time getTime(int columnIndex)


Obtiene el valor de una columna como un objeto java.sql.Time.

Time getTime(int columnIndex, Calendar cal)


Obtiene el valor de una columna como un java.sql.Time.

Time getTime(String columnName)


Obtiene el valor de una columna como un java.sql.Time.

Time getTime(String columnName, Calendar cal)


Obtiene el valor de una columna como un java.sql.Time.

int getType()
JDBC 2.0 Devuelve el tipo de este ResultSet.

SQLWarning getWarnings()
Retorna el primer warning comunicado en llamadas a este
ResultSet.

void insertRow()
JDBC 2.0 Inserta los contenidos del registro en el objeto
ResultSet y en la base de datos.

boolean isAfterLast()
JDBC 2.0 Detecta si el cursor está después del último registro.

boolean isBeforeFirst()
JDBC 2.0 Detecta si el cursor está antes del primer registro.

boolean isFirst()
JDBC 2.0 Detecta si el cursor está en el primer registro.

Campus Impúlsate | [email protected]


boolean isLast()
JDBC 2.0 Detecta si el cursor está en el último registro.

boolean last()
JDBC 2.0 No sitúa en el último registro.

boolean next()
Mueve el cursor al siguiente registro.

boolean previous()
JDBC 2.0 Mueve el cursor al registro anterior.

void refreshRow()
JDBC 2.0 Refresca la fila actual con su valor más reciente en la
base de datos.

boolean relative(int rows)


JDBC 2.0 Nos movemos el número de registros indicando desde
la posición actual.

boolean rowDeleted()
JDBC 2.0 Indica si un registro ha sido borrado. Contrasta nuestro
ResultSet con la base de datos.

boolean rowInserted()
JDBC 2.0 Indica si el registro actual ha sufrido alguna inserción.

boolean rowUpdated()
JDBC 2.0 Indica si el registro actual ha sido actualizado.

void updateBigDecimal(int columnIndex, BigDecimal x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor BigDecimal indicado.

void updateBigDecimal(String columnName, BigDecimal x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor BigDecimal indicado.

void updateBoolean(int columnIndex, boolean x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor boolean indicado.

void updateBoolean(String columnName, boolean x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor boolean indicado.

void updateByte(int columnIndex, byte x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor byte indicado.

void updateByte(String columnName, byte x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor byte indicado.

Campus Impúlsate | [email protected]


void updateBytes(int columnIndex, byte[] x)
JDBC 2.0 Actualiza la columna indicada del registro actual con el
array de bytes indicado.

void updateBytes(String columnName, byte[] x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
array de bytes indicado.

void updateDate(int columnIndex, Date x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor Date indicado.

void updateDate(String columnName, Date x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor Date indicado.

void updateDouble(int columnIndex, double x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor double indicado.

void updateDouble(String columnName, double x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor double indicado.

void updateFloat(int columnIndex, float x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor float indicado.

void updateFloat(String columnName, float x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor float indicado.

void updateInt(int columnIndex, int x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor int indicado.

void updateInt(String columnName, int x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor int indicado.

void updateLong(int columnIndex, long x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor long indicado.

void updateLong(String columnName, long x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor long indicado.

void updateNull(int columnIndex)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor null indicado.

Campus Impúlsate | [email protected]


void updateNull(String columnName)
JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor null indicado.

void updateObject(int columnIndex, Object x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor Object indicado.

void updateObject(String columnName, Object x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor Object indicado.

void updateRow()
JDBC 2.0 Actualiza la base de datos con los nuevos contenidos
del registro actual.

void updateShort(int columnIndex, short x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor short indicado.

void updateShort(String columnName, short x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor short indicado.

void updateString(int columnIndex, String x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor String indicado.

void updateString(String columnName, String x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor String indicado.

void updateTime(int columnIndex, Time x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor Time indicado.

void updateTime(String columnName, Time x)


JDBC 2.0 Actualiza la columna indicada del registro actual con el
valor Time indicado.

boolean wasNull()
Comunica si la última columna leída tiene un valor SQL nulo.

Campus Impúlsate | [email protected]


Para obtener información relativa a cada campo basta con utilizar el método
getMetaData() sobre el objeto ResultSet y obtenemos un
objeto ResultSetMetaData sobre el que se pueden usar los siguientes métodos:

Métodos de
ResultSetMetaData

int getColumnCount()
Devuelve el número de columnas de este ResultSet.

int getColumnDisplaySize(int column)


Indica el ancho máximo de la columna especificada en
caracteres.

String getColumnName(int column)


Devuelve el nombre de la columna especificada.

int getColumnType(int column)


Devuelve el tipo SQL de la columna especificada.

String getColumnTypeName(int column)


Devuelve el tipo de dato de la columna según la base
de datos.

int getPrecision(int column)


Obtiene la precisión usada en la columna. Tiene
sentido en datos decimales.

int getScale(int column)


Obtiene el número de dígitos usados a la derecha del
punto decimal.

String getTableName(int column)


Gets a column's table name.

boolean isAutoIncrement(int column)


Indica si la columna especificada es automáticamente
numerada, esto es de sólo lectura.

boolean isCaseSensitive(int column)


Indica si la columna indicada es sensible a mayúsculas
y minúsculas.

boolean isCurrency(int column)


Indica se la columna indicada es un valor de moneda.

int isNullable(int column)


Indica si la columna indicada permite valores null.

boolean isReadOnly(int column)


Indica si la columna indicada es de sólo lectura.

Campus Impúlsate | [email protected]


boolean isSearchable(int column)
Indica si la columna puede ser usada en un claúsula
where.

boolean isSigned(int column)


Indica si los valores de la columna especificada son
número con signo.

boolean isWritable(int column)


Indica si se puede escribir en la columna especificada.

Ejemplo de carga de datos

Vamos a realizar una página JSP que contendrá un desplegable con todos los oficios
de la tabla empleados.

El desplegable lo cargaremos mediante código en la página JSP.

Posteriormente, cuando el usuario seleccione el oficio de un empleado, mostraremos


los empleados que tienen dicho oficio.

Lo primero que vamos a realizar será crearnos un nuevo proyecto Web Application.

Campus Impúlsate | [email protected]


Le daremos el nombre de ProyectoJSP.

Utilizaremos el servidor Glassfish por defecto.

Campus Impúlsate | [email protected]


No implementaremos ningún Framework.

A continuación, nos crearemos una nueva página JSP.

Campus Impúlsate | [email protected]


Le daremos el nombre empleadosoficios

Lo que debemos realizar ahora es el acceso mediante JDBC a la tabla EMP de Oracle.
Para ello, debemos agregar dentro de la carpeta Libraries el conector JDBC para
Oracle.

Este conector lo podremos descargar desde: https://code.google.com/p/cat200-1-


2010/downloads/detail?name=classes12.jar&can=2&q=

Campus Impúlsate | [email protected]


Ahora implementaremos el código de la página JSP para mostrar en una lista los
oficios y poder recuperar los empleados.

<%@page contentType="text/html" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd">

<%@page import="java.sql.*" %>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Empleados por oficio</title>

</head>

<body>

<%try {

DriverManager.registerDriver(new oracle.jdbc.OracleDriver());

Connection cn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE",
"SYSTEM", "12345");

Campus Impúlsate | [email protected]


Statement sentencia =
cn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_R
EAD_ONLY);

ResultSet rs = sentencia.executeQuery("SELECT DISTINCT JOB FROM EMP");%>

<H1>Oficios de Empleados</H1>

<FORM method='POST' action='empleadosoficios.jsp' name='form1'>

<SELECT NAME='cmboficio'>

<% String oficio="";

String opcioneshtml="";

oficio = request.getParameter("cmboficio");

while (rs.next())

String opcion = rs.getString(1);

if (opcion!=null && opcion.equals(oficio))

opcioneshtml += "<OPTION VALUE='"+opcion+"' SELECTED>"+opcion+"</OPTION>";

}else{

opcioneshtml += "<OPTION VALUE='"+opcion+"'>"+opcion+"</OPTION>";

}%>

<%=opcioneshtml%>

</SELECT>

<INPUT TYPE='SUBMIT' VALUE='Ver empleados' NAME='btnbuscar'>

</FORM>

<%

String tabla="";

if (oficio!=null)

Campus Impúlsate | [email protected]


{

PreparedStatement pst = cn.prepareStatement("SELECT ENAME, JOB, DEPTNO


FROM EMP WHERE JOB=?");

pst.setString(1, oficio);

rs = pst.executeQuery();

tabla="<table border='1'>";

while (rs.next())

tabla += "<tr><td>"+rs.getString(1)+"</td></tr>";

tabla += "<tr><td>"+rs.getString(2)+"</td></tr>";

tabla += "<tr><td>"+rs.getString(3)+"</td></tr>";

tabla += "</table>";%>

<%=tabla%>

<%}%>

<%} catch (SQLException ex) {%>

<h1>Error: <%=ex.toString()%></h1>

<%}%>

</body>

</html>

Ya podremos ejecutar nuestro proyecto y comprobar el funcionamiento correcto de la


aplicación:

Campus Impúlsate | [email protected]


Ejecución de consultas de manipulación de datos

La forma de lanzar consultas de actualización, borrado y modificación (DML, Data


Manipulation Language, como INSERT, DELETE y UPDATE) de la base de datos es
parecida a la de la consulta, pero a la hora de lanzar la consulta se utilizara el método
excuteUpdate().

DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection cn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE",
"SYSTEM", "12345");
Statement actualizacion= cn.createStatement("");
actualizacion.executeUpdate("DELETE FROM autores WHERE id = 101");

Este método retorna un entero que indica el número de filas afectadas por la consulta.

También se puede utilizar el método execute(), que sirve para todas las consultas.
Simplemente retorna verdadero si se ha retornado un objeto ResultSet y falso si se ha
retornado un entero o nada.

El usuario necesitará los permisos necesarios sobre la base de datos.

Ejecución de consultas de definición de datos

La forma de lanzar consultas de definición de datos (DDL, Data Definition Language,


como CREATE y ALTER) de la base de datos es parecida a la de la consulta, pero a la
hora de lanzar la consulta se utilizará el método excuteUpdate().

DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection cn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE",
"SYSTEM", "12345");
Statement actualizacion= cn.createStatement();
actualizacion.executeUpdate("ALTER table autor add (ultima_publicacion_autor
date");

Campus Impúlsate | [email protected]


Este método retorna un entero que indica el número de filas afectadas por la consulta.
También se puede utilizar el método execute(), que sirve para cualquier tipo de consulta.
Simplemente retorna verdadero si se ha retornado un objeto ResultSet y falso si se ha
retornado un entero o nada.

El usuario necesitará los permisos necesarios sobre la base de datos.

Ejemplo completo de consultas sobre una base de datos

A continuación se muestra el código necesario para crear una tabla de usuarios, y


después realizar consultas, inserciones, modificaciones y borrado de los datos. Se
puede probar desde un proyecto de Netbeans o bien por línea de comandos.

Creación de la tabla

Creamos la tabla DBUSER, con los campos id, username, created_by y created_date.

package com.demo.jdbc;
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCStatementCreateExample {


private static final String DB_DRIVER = "oracle.jdbc.driver.OracleDriver";
private static final String DB_CONNECTION = "jdbc:oracle:thin:@localhost:1521:XE";
private static final String DB_USER = "user";
private static final String DB_PASSWORD = "password";
public static void main(String[] argv) {
try {
createDbUserTable();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
private static void createDbUserTable() throws SQLException {
Connection dbConnection = null;
Statement statement = null;

String createTableSQL = "CREATE TABLE DBUSER("


+ "USER_ID NUMBER(5) NOT NULL, "
+ "USERNAME VARCHAR(20) NOT NULL, "
+ "CREATED_BY VARCHAR(20) NOT NULL, "
+ "CREATED_DATE DATE NOT NULL, " + "PRIMARY KEY (USER_ID) "
+ ")";
try {
dbConnection = getDBConnection();
statement = dbConnection.createStatement();
System.out.println(createTableSQL);
// execute the SQL stetement
statement.execute(createTableSQL);
System.out.println("Tabla \"dbuser\" is creada!");
} catch (SQLException e) {
System.out.println(e.getMessage());

Campus Impúlsate | [email protected]


} finally {
if (statement != null) {
statement.close();
}
if (dbConnection != null) {
dbConnection.close();
}
}

}
private static Connection getDBConnection() {
Connection dbConnection = null;

try {
Class.forName(DB_DRIVER);
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}
try {
dbConnection = DriverManager.getConnection(
DB_CONNECTION, DB_USER,DB_PASSWORD);
return dbConnection;
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return dbConnection;
}

Inserción en la tabla

Creamos la tabla DBUSER, con los campos id, username, created_by y created_date.

package com.demo.jdbc;
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class JDBCStatementInsertExample {

private static final String DB_DRIVER = "oracle.jdbc.driver.OracleDriver";


private static final String DB_CONNECTION = "jdbc:oracle:thin:@localhost:1521:XE";
private static final String DB_USER = "user";
private static final String DB_PASSWORD = "password";
private static final DateFormat dateFormat = new SimpleDateFormat(
"yyyy/MM/dd HH:mm:ss");

public static void main(String[] argv) {


try {

Campus Impúlsate | [email protected]


insertRecordIntoDbUserTable();
} catch (SQLException e) {
System.out.println(e.getMessage());
}

private static void insertRecordIntoDbUserTable() throws SQLException {


Connection dbConnection = null;
Statement statement = null;

String insertTableSQL = "INSERT INTO DBUSER"


+ "(USER_ID, USERNAME, CREATED_BY, CREATED_DATE) " + "VALUES"
+ "(1,'admin','system', " + "to_date('"
+ getCurrentTimeStamp() + "', 'yyyy/mm/dd hh24:mi:ss'))";

try {
dbConnection = getDBConnection();
statement = dbConnection.createStatement();
System.out.println(insertTableSQL);
// execute insert SQL stetement
statement.executeUpdate(insertTableSQL);
System.out.println("Registro insertado en DBUSER!");
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
if (statement != null) {
statement.close();
}
if (dbConnection != null) {
dbConnection.close();
}

}
}

private static Connection getDBConnection() {


Connection dbConnection = null;
try {
Class.forName(DB_DRIVER);
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}
try {
dbConnection = DriverManager.getConnection(
DB_CONNECTION, DB_USER,DB_PASSWORD);
return dbConnection;
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return dbConnection;
}

private static String getCurrentTimeStamp() {


java.util.Date today = new java.util.Date();

Campus Impúlsate | [email protected]


return dateFormat.format(today.getTime());
}
}

Inserción de varios registros

Es posible lanzar varias consultas en un mismo comando, utilizando el método


executeBatch().

package com.demo.jdbc;

import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class JDBCBatchUpdateExample {


private static final String DB_DRIVER = "oracle.jdbc.driver.OracleDriver";
private static final String DB_CONNECTION = "jdbc:oracle:thin:@localhost:1521:XE";
private static final String DB_USER = "user";
private static final String DB_PASSWORD = "password";
private static final DateFormat dateFormat = new SimpleDateFormat(
"yyyy/MM/dd HH:mm:ss");

public static void main(String[] argv) {


try {
batchInsertRecordsIntoTable();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}

private static void batchInsertRecordsIntoTable() throws SQLException {


Connection dbConnection = null;
Statement statement = null;

String insertTableSQL1 = "INSERT INTO DBUSER"


+ "(USER_ID, USERNAME, CREATED_BY, CREATED_DATE) " + "VALUES"
+ "(101,'usuario1','system', " + "to_date('"
+ getCurrentTimeStamp() + "', 'yyyy/mm/dd hh24:mi:ss'))";

String insertTableSQL2 = "INSERT INTO DBUSER"


+ "(USER_ID, USERNAME, CREATED_BY, CREATED_DATE) " + "VALUES"
+ "(102,'usuario2','system', " + "to_date('"
+ getCurrentTimeStamp() + "', 'yyyy/mm/dd hh24:mi:ss'))";

String insertTableSQL3 = "INSERT INTO DBUSER"


+ "(USER_ID, USERNAME, CREATED_BY, CREATED_DATE) " + "VALUES"
+ "(103,'usuario3','system', " + "to_date('"
+ getCurrentTimeStamp() + "', 'yyyy/mm/dd hh24:mi:ss'))";

try {

Campus Impúlsate | [email protected]


dbConnection = getDBConnection();
statement = dbConnection.createStatement();
dbConnection.setAutoCommit(false);
statement.addBatch(insertTableSQL1);
statement.addBatch(insertTableSQL2);
statement.addBatch(insertTableSQL3);
statement.executeBatch();
dbConnection.commit();
System.out.println("Se han insertado varios registros en DBUSER!");
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {

if (statement != null) {
statement.close();
}

if (dbConnection != null) {
dbConnection.close();
}
}
}

private static Connection getDBConnection() {


Connection dbConnection = null;
try {
Class.forName(DB_DRIVER);
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}

try {
dbConnection = DriverManager.getConnection(
DB_CONNECTION, DB_USER,DB_PASSWORD);
return dbConnection;

} catch (SQLException e) {
System.out.println(e.getMessage());
}
return dbConnection;
}

private static String getCurrentTimeStamp() {


java.util.Date today = new java.util.Date();
return dateFormat.format(today.getTime());
}
}

Campus Impúlsate | [email protected]


Selección en la tabla

Mediante un Resultset seleccionamos y mostramos todos los datos de la tabla.

package com.demo.jdbc;
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCStatementSelectExample {


private static final String DB_DRIVER = "oracle.jdbc.driver.OracleDriver";
private static final String DB_CONNECTION = "jdbc:oracle:thin:@localhost:1521:XE";
private static final String DB_USER = "user";
private static final String DB_PASSWORD = "password";

public static void main(String[] argv) {


try {
selectRecordsFromDbUserTable();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}

private static void selectRecordsFromDbUserTable() throws SQLException {


Connection dbConnection = null;
Statement statement = null;
String selectTableSQL = "SELECT USER_ID, USERNAME from DBUSER";
try {
dbConnection = getDBConnection();
statement = dbConnection.createStatement();
System.out.println(selectTableSQL);
// execute select SQL stetement
ResultSet rs = statement.executeQuery(selectTableSQL);
while (rs.next()) {
String userid = rs.getString("USER_ID");
String username = rs.getString("USERNAME");
System.out.println("userid : " + userid);
System.out.println("username : " + username);
}
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
if (statement != null) {
statement.close();
}

if (dbConnection != null) {
dbConnection.close();
}
}
}

private static Connection getDBConnection() {

Campus Impúlsate | [email protected]


Connection dbConnection = null;
try {
Class.forName(DB_DRIVER);

} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}
try {
dbConnection = DriverManager.getConnection(DB_CONNECTION, DB_USER,
DB_PASSWORD);
return dbConnection;
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return dbConnection;
}
}

Actualización de registros

Actualización del nombre del usuario con id 1 al valor "administrador".

package com.demo.jdbc;

import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCStatementUpdateExample {


private static final String DB_DRIVER = "oracle.jdbc.driver.OracleDriver";
private static final String DB_CONNECTION = "jdbc:oracle:thin:@localhost:1521:XE";
private static final String DB_USER = "user";
private static final String DB_PASSWORD = "password";
public static void main(String[] argv) {
try {
updateRecordIntoDbUserTable();
} catch (SQLException e) {
System.out.println(e.getMessage());
}

private static void updateRecordIntoDbUserTable() throws SQLException {


Connection dbConnection = null;
Statement statement = null;
String updateTableSQL = "UPDATE DBUSER"
+ " SET USERNAME = 'administrador' "
+ " WHERE USER_ID = 1";
try {
dbConnection = getDBConnection();
statement = dbConnection.createStatement();

Campus Impúlsate | [email protected]


System.out.println(updateTableSQL);
// execute update SQL stetement
statement.execute(updateTableSQL);
System.out.println("Usuario actualizado en la tabla DBUSER!");
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
if (statement != null) {
statement.close();
}
if (dbConnection != null) {
dbConnection.close();
}
}
}

private static Connection getDBConnection() {


Connection dbConnection = null;

try {
Class.forName(DB_DRIVER);
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}
try {
dbConnection = DriverManager.getConnection(
DB_CONNECTION, DB_USER,DB_PASSWORD);
return dbConnection;
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return dbConnection;
}
}

Borrado de registros

Borrado del usuario con id 1.

package com.demo.jdbc;

import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCStatementDeleteExample {


private static final String DB_DRIVER = "oracle.jdbc.driver.OracleDriver";
private static final String DB_CONNECTION = "jdbc:oracle:thin:@localhost:1521:XE";
private static final String DB_USER = "user";
private static final String DB_PASSWORD = "password";

public static void main(String[] argv) {


try {

Campus Impúlsate | [email protected]


deleteRecordFromDbUserTable();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}

private static void deleteRecordFromDbUserTable() throws SQLException {


Connection dbConnection = null;
Statement statement = null;

String deleteTableSQL = "DELETE DBUSER WHERE USER_ID = 1";


try {
dbConnection = getDBConnection();
statement = dbConnection.createStatement();
System.out.println(deleteTableSQL);
// execute delete SQL stetement
statement.execute(deleteTableSQL);
System.out.println("Registro borrado de la tabla DBUSER!");
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
if (statement != null) {
statement.close();
}
if (dbConnection != null) {
dbConnection.close();
}
}
}

private static Connection getDBConnection() {


Connection dbConnection = null;
try {
Class.forName(DB_DRIVER);
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}

try {

dbConnection = DriverManager.getConnection(
DB_CONNECTION, DB_USER,DB_PASSWORD);
return dbConnection;

} catch (SQLException e) {
System.out.println(e.getMessage());
}
return dbConnection;
}
}

Campus Impúlsate | [email protected]


Gestión de transacciones

Una transacción es una colección de sentencias DML (Manipulación de datos) que


forman una unidad lógica de trabajo o procesamiento, con unas propiedades bien
definidas. De esta forma constituyen un conjunto de operaciones sobre los datos en una
base de datos que o se ejecuta entera o no se ejecuta ninguna de sus sentencias.

JDBC permite que las declaraciones de SQL sean agrupadas juntas en una sola
transacción. De esta forma se puede garantizar la atomicidad y consistencia de datos,
usando las características transaccionales de JDBC.

Componentes de una base de datos

Iniciar una transacción

El control de la transacción es llevado a cabo por el objeto de la conexión. A la hora


de crear una conexión, el modo está activado por defecto, lo que significa que cada
declaración individual de SQL es tratada como transacción por sí misma, y será aplicada
en cuanto finalice la ejecución.

El método setAutoCommit es el encargado de establecer si se trabaja agrupando


varias sentencias en una transacción, o por el contrario cada sentencia SQL será una
transacción independiente. Para trabajar con varias sentencias SQL agrupadas en una
transacción es necesario establecer el auto-commit a false.

conexion.setAutoCommit(false);

Como es lógico, por defecto auto-commit está establecido a true.

Campus Impúlsate | [email protected]


Detener una transacción

Cuanto auto-commit esta a false, para poder aplicar los cambios provocados por las

consultas de la transacción en la base de datos, es necesario llamar al método commit().

Si no se llama al método commit(), los cambios no se verán reflejados en la base de

datos a pesar de que se hayan ejecutadas una o más sentencias SQL.

El método commit() pertenece a la conexión, y la forma de invocarlo es la siguiente:

conexion.commit();

Respuesta tras error

Si antes de invocar el método commit() se invoca el método rollback(), todas las


sentencias que se hayan ejecutado quedaran sin efecto. rollback() vuelve atrás todos
los cambios realizados sobre los datos desde el ultimo commit() realizado.

El método rollback() también pertenece a la conexión, y la forma de invocarlo es la


siguiente:

conexión.rollback()

Ejemplo de transacción

Vemos un ejemplo que se centra en la transacción, obviando la gestión de la


conexión y de lanzamiento de consultas de inserción. La transacción está compuesta
por tres consultas de inserción de alumnos.

// Declara la conexión
Connection cn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE",
"SYSTEM", "12345");
//Declara los alumnos a insertar
Alumno a1 = new Alumno(“José”);
Alumno a2 = new Alumno(“Luis”);
Alumno a3 = new Alumno(“Miguel”);
try{
// Define la conexión
cn = AdministradorDeConexiones.getConnection();
// Se asigna falso a auto-commit
cn.setAutoCommit(false);
//Comienzo de la transacción
a1.insertar(cn);
a2.insertar(cn);
a3.insertar(cn);

Campus Impúlsate | [email protected]


// Confirmar los cambios
cn.commit();
} catch(Exception e) {
try{
// Vuelve atrás los cambios
cn.rollback();
}
catch(Exception e){//Gestión de errores}
} finally{
try{
// Cierra la conexión
if( cn != null )
cn.close();
}
catch(Exception e){//Gestión de errores}
}

Ejemplo completo de transacción

Vamos a ver un caso de actualización de la ya conocida tabla DBUSER, con y sin


transacción. Veremos como los cambios se hacen de forma parcial en caso de error.
Podemos utilizar el código de conexión de los ejemplos anteriores.

Utilizaremos el método prepareStatement(), para dar valores a los parámetros de las


consultas (?). Lógicamente se podría haber echo escribiendo los datos directamente en
cada consulta. Pero es interesante ver la gestión de estos parámetros, que dan mayor
flexibilidad, como por ejemplo lanzar varias veces la consulta con distintos valores.

Sin transacción

Recordemos que el método excecuteUpdate() tiene autocommit por defecto. Por lo


que ante un error los datos quedarán parcialmente actualizados.

String insertTableSQL = "INSERT INTO DBUSER"


+ "(USER_ID, USERNAME, CREATED_BY, CREATED_DATE) VALUES"
+ "(?,?,?,?)";

String updateTableSQL = "UPDATE DBUSER SET USERNAME =? "


+ "WHERE USER_ID = ?";

preparedStatementInsert = dbConnection.prepareStatement(insertTableSQL);
preparedStatementInsert.setInt(1, 999);
preparedStatementInsert.setString(2, "usuario101");
preparedStatementInsert.setString(3, "system");
preparedStatementInsert.setTimestamp(4, getCurrentTimeStamp());
preparedStatementInsert.executeUpdate(); //Datos actualizados en la base de datos.

preparedStatementUpdate = dbConnection.prepareStatement(updateTableSQL);
preparedStatementUpdate.setString(1, "Una cadena demasiado larga causará un

Campus Impúlsate | [email protected]


error en la base de datos...");
preparedStatementUpdate.setInt(2, 999);

preparedStatementUpdate.executeUpdate(); //Error, cadena demasiado larga, no se


lleva a cabo la actualización.

Como vemos, la primera consulta se ejecuta correctamente, con lo que el usuario 999
se crea en la base de datos. Sin embargo, la segunda consulta falla, con lo que la
actualización no se lleva a cabo y el registro queda con los valores iniciales sin
actualizar.

Con transacción

La solución será incluir las dos operaciones en una transacción, con lo que ante el error
se cancelan todos los cambios, y se evita incluir el usuario 999 inconsistente.

La instrucción que causa el error se puede comentar y utilizar la que hay justo debajo
que no causaría error.

package com.demo.jdbc;

import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class JDBCTransactionExample {


private static final String DB_DRIVER = "oracle.jdbc.driver.OracleDriver";
private static final String DB_CONNECTION = "jdbc:oracle:thin:@localhost:1521:XE";
private static final String DB_USER = "user";
private static final String DB_PASSWORD = "password";

public static void main(String[] argv) throws SQLException {


Connection dbConnection = null;
PreparedStatement preparedStatementInsert = null;
PreparedStatement preparedStatementUpdate = null;

String insertTableSQL = "INSERT INTO DBUSER"


+ "(USER_ID, USERNAME, CREATED_BY, CREATED_DATE) VALUES"
+ "(?,?,?,?)";
String updateTableSQL = "UPDATE DBUSER SET USERNAME =? "
+ "WHERE USER_ID = ?";
try {
dbConnection = getDBConnection();
dbConnection.setAutoCommit(false);
preparedStatementInsert = dbConnection.prepareStatement(insertTableSQL);
preparedStatementInsert.setInt(1, 999);
preparedStatementInsert.setString(2, "usuario101");
preparedStatementInsert.setString(3, "system");
preparedStatementInsert.setTimestamp(4, getCurrentTimeStamp());
preparedStatementInsert.executeUpdate();

preparedStatementUpdate = dbConnection.prepareStatement(updateTableSQL);

Campus Impúlsate | [email protected]


preparedStatementUpdate.setString(1,
"Una cadena demasiado larga causará un error en la base de datos...");
//preparedStatementUpdate.setString(1, "nueva cadena");
preparedStatementUpdate.setInt(2, 999);
preparedStatementUpdate.executeUpdate();
dbConnection.commit();
System.out.println("Todas las consultas hechas!");
} catch (SQLException e) {
System.out.println(e.getMessage());
dbConnection.rollback();
} finally {
if (preparedStatementInsert != null) {
preparedStatementInsert.close();
}
if (preparedStatementUpdate != null) {
preparedStatementUpdate.close();
}
if (dbConnection != null) {
dbConnection.close();
}
}
}

private static Connection getDBConnection() {


Connection dbConnection = null;
try {
Class.forName(DB_DRIVER);
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}
try {
dbConnection = DriverManager.getConnection(DB_CONNECTION, DB_USER,
DB_PASSWORD);
return dbConnection;
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return dbConnection;
}

private static java.sql.Timestamp getCurrentTimeStamp() {


java.util.Date today = new java.util.Date();
return new java.sql.Timestamp(today.getTime());
}
}

Campus Impúlsate | [email protected]


Excepciones del API JDBC

El manejo de excepciones nos permite manejar condiciones excepcionales tales como


errores definidos por el programa de forma controlada.

Cuando se produce una condición de excepción, se lanza una excepción. Entonces la


ejecución del programa actual se detiene y el control se redirige a la cláusula de captura
(catch) aplicable más cercana. Si no existe una cláusula catch aplicable, entonces la
ejecución del programa finaliza.

El manejo de excepciones JDBC es muy similar al manejo de excepciones general


de Java, pero para JDBC, la excepción más común con la que trataremos será
java.sql.SQLException.

El objeto pasado SQLException tiene los siguientes métodos disponibles para


recuperar información adicional sobre la excepción:

1. getErrorCode ()

Obtiene el número de error asociado con la excepción.

2. getMessage ()

Obtiene el mensaje de error del controlador JDBC para un error, manejado por el

controlador u obtiene el número de error de Oracle y el mensaje de un error de base

de datos.

3. getSQLState ()

Obtiene la cadena XOPEN SQLstate. Para un error de controlador JDBC, no se

devuelve información útil de este método. Para un error de base de datos, se devuelve

el código de cinco dígitos XOPEN SQLstate. Este método puede devolver nulo.

4. getNextException ()

Obtiene el siguiente objeto de excepción en la cadena de excepciones.

5. printStackTrace ()

Imprime la excepción actual, o throwable, en la salida de error estándar (generalmente

la pantalla).

Campus Impúlsate | [email protected]


6. printStackTrace (PrintStream s)

Imprime este throwable en el flujo de impresión que especifique.

7. printStackTrace (PrintWriter w)

Imprime este throwable en el escritor de impresión que especifique.

Campus Impúlsate | [email protected]

También podría gustarte