Crear y recorrer un cursor de Oracle

Crear y recorrer un cursor de oracle
Dejo en este post cómo crear un cursor oracle sobre una consulta para recorrerlo después:

-- Zona de declaración 
declare
-- Declaramos el cursor sobre una consulta de una supuesta tabla usuarios.

cursor usuarios is 
    select * 
    from usuarios
    where edad > 20;

-- Fin declaración. Comenzamos el procedimento:

begin

-- Recorremos el cursor con un bucle for - loop
    for u in usuarios loop
        dbms_output.put_line(u.apellidos||' '||u.nombre);
    end loop; 
-- Fin bucle

end; 
-- Fin procedimiento



La función dbms_output.put_line muestra por pantalla el resultado en la variable "u" con la que recorremos el cursor. El operador || es de concatenación de cadenas.

Quizás te interese...

spacer

JNDI (Java Naming Directory Interface). Configurando recursos en Tomcat.

La Java Naming and Directory Interface (JNDI) es una interfaz de programación (API) que proporciona funcionalidades de nombrado y directorio a las aplicaciones escritas usando Java. Está definido para ser independiente de cualquier implementación de servicio de directorio. Así se puede acceder a una gran variedad de directorios de una forma común.

Sirve para configurar recursos compartidos para aplicaciones java organizándolos por directorio con nombres únicos. Es un servicio de nombres que permite:
  • Asociar nombres con objetos.
  • Permitir la búsqueda de un objeto por su nombre.
En el mercado existen diferentes servicios de directorios, por ejemplo:
  • LDAP (Lightweight Directory Access Protocol)
  • NDS (Novell Directory Service)
  • NIS (Network Information Service)
Cada servicio tiene una forma de acceso diferente, lo que implica que si se cambia de fabricante hay que reescribir los clientes. Es por eso que se usa JNDI como capa por encima pues ofrece un acceso común a los recursos configurados.

La API JNDI  permite escribir código Java que realice operaciones sobre directorios. Es una API uniforme a todos los tipos de servicios de directorios. Es similar a JDBC.

Service Provider Interface (SPI) permite acceder al servicio de directorio específico de cada fabricante. Mapea código JNDI en operaciones específicas de directorios. Es un driver JNDI.

 Arquitectura JNDI

Un ejemplo sencillo

Vamos a configurar un pool de conexiones para una base de datos en el lado del servidor. A continuación se muestra cómo se usaría el API JNDI:

String jndiName = "jdbc/<alias>";
//Obtenemos el contexto inicial (dónde comienza el directorio de nombres)
InitialContext ctx = new InitialContext();
//Asignamos el recurso a un objeto de tipo DataSource (Binding)
DataSource ds = (DataSource) ctx.lookup(jndiName);
Connection conn = ds.getConnection();
// hacer algo con la conexión
conn.close();
ctx.close();


El código anterior funcionaría en todas las aplicaciones que tengamos desplegada en nuestro servidor web (en nuestro caso lo que es Tomcat) o servidor de aplicaciones. Se usa en todas las aplicaciones del servidor y solo lo configuramos una vez.

La configuración que hay que realizar en Tomcat es la siguiente: 
  1.  Modificar el fichero ../conf/server.xml  de Tomcat entre las etiquetas <GlobalNamingResources> y </GlobalNamingResources>
  2. <GlobalNamingResources>
    …
    <Resource name="jdbc/<alias>"
       auth="Container"
       type="oracle.jdbc.pool.OracleDataSource"
       driverClassName="oracle.jdbc.driver.OracleDriver"
       factory="oracle.jdbc.pool.OracleDataSourceFactory"
       url="jdbc:oracle:thin:@<host>:<port>:<sid>"
       [user=<user>]
       [password=<password>]
       maxActive="20"
       maxIdle="10"
       maxWait="-1" />
    …
    </GlobalNamingResources> 
    
    
    Estamos configurando una fuente de datos (dataSource) para poder acceder a una base de datos Oracle. Indicando al servidor que tenemos un recurso. A continuación indicamos a nuestras aplicaciones que pueden hacer uso del recurso definido en el servidor:
  3. Modificar el fichero /conf/context.xml entre las etiquetas <Context> y </Context> con lo siguiente:
  4. <Context>
    …
    <ResourceLink global="jdbc/<alias>" name="jdbc/<alias>" 
    type="oracle.jdbc.pool.OracleDataSource"/>
    …
    </Context> 
    
  5. Incluir el jar del conector jdbc a la base de datos en la carpeta lib del servidor Tomcat, no del proyecto. Y, muy importante, reiniciar el servidor.
spacer

Paquetes (package) en Oracle

Los paquetes en Oracle sirven para agrupar y organizar funcionalidades en una base de datos. Son estructuras que agrupan objetos PL/SQL (funciones, procedimientos, tipos, etc.). Ello nos va a permitir tener programas estructurados agrupados por funcionalidades.
Un paquete de Oracle se compone de dos elementos: 
  • La especificación (cabecera) y
  • El cuerpo
La especificación es la interfaz de las funciones y procedimientos que se van a implmentar en el cuerpo, es algo parecido a las cabeceras en el lenguaje de programación C. La sintaxis general es la siguiente:
CREATE [OR REPLACE] PACKAGE <nombre_del_paquete> is 

  -- Declaración de tipos:
  TYPE <nombreTipo> IS <tipo>;

  -- Declaracion de variables y constantes
  <nombreConstante> CONSTANT <tipo> := <valor>;
  <nombreVariable> <tipo>;

  -- Declaraciones de funciones y procedimientos
  FUNCTION <nombreFuncion>(<parametro> <tipo>,...) RETURN <tipo>;
  PROCEDURE <nombreProcedimiento>(<parametro> <tipo>, ...);

END <nombre_del_paquete>


El cuerpo no es más que la implementación de la especificación que hemos realizado. Por tanto, el cuerpo del paquete debe implementar lo que se ha declarado en la especificación. La sintaxis del cuerpo es parecida a la de la especificación, con la diferencia de que incluimos la implementación de cada procedimiento y función. Declaramos el cuerpo con la palabra clave BODY. La sintaxis general es la siguiente:
CREATE [OR REPLACE] PACKAGE BODY <nombre_del_paquete> IS
   
  -- Declaraciones de tipos y registros privados
  TYPE <TypeName> IS <tipo>;
  
  -- Declaraciones de variables y constantes privadas
  <nombreConstante> CONSTANT <tipo> := <valor>;
  <nombreVariable> <tipo>;

  -- Implementacion de procedimientos y funciones 
  FUNCTION <nombreFuncion>(<parametro> <tipo>,...) RETURN <tipo> IS
    -- Variables locales de la funcion
  BEGIN
    -- Implementación de la función
    return <resultado>;
  [EXCEPTION]
    -- Control de excepciones
  END;
  
  PROCEDURE <nombreProcedimiento>(<parametro> <tipo>, ...) IS 
   -- Variables locales del procedimiento
  BEGIN
    -- Implementacion de procedimiento
  [EXCEPTION]
    -- Control de excepciones
  END;

END <nombre_del_paquete>;


Espero que os sirva, próximamente escribiré sobre procedimientos y funciones con algunos ejemplos.

Un saludo!
spacer