## Sentencias SQL para crear un Procedimiento Almacenado

Esta página muestra un procedimiento almacenado muy sencillo que no tiene parámetros. Aunque la mayoría de los procedimientos almacenados hacen cosas más complejas que este ejemplo, sirve para ilustrar algunos puntos básicos sobre ellos. Como paso prévio, la sintaxis para definir un procedimiento almacenado es diferente de un controlador de base de datos a otro. Por ejemplo, algunos utilizan begin . . . end u otras palabras clave para indicar el principio y final de la definición de procedimiento. En algunos controladores, la siguiente sentencia SQL crea un procedimiento almacenado:

    create procedure SHOW_SUPPLIERS
    as
    select SUPPLIERS.SUP_NAME, COFFEES.COF_NAME
    from SUPPLIERS, COFFEES
    where SUPPLIERS.SUP_ID = COFFEES.SUP_ID
    order by SUP_NAME

El siguiente código pone la sentencia SQL dentro de un string y lo asigna a la variable createProcedure, que utilizaremos más adelante:

    String createProcedure = "create procedure SHOW_SUPPLIERS " +
    				"as " +
    				"select SUPPLIERS.SUP_NAME, COFFEES.COF_NAME " +
    				"from SUPPLIERS, COFFEES " +
    				"where SUPPLIERS.SUP_ID = COFFEES.SUP_ID " +
    				"order by SUP_NAME";

El siguiente fragmento de código utiliza el objeto Connection, con para crear un objeto Statement, que es utilizado para enviar la sentencia SQL que crea el procedimiento almacenado en la base de datos:

    Statement stmt = con.createStatement();
    stmt.executeUpdate(createProcedure);

El procedimiento SHOW_SUPPLIERS será compilado y almacenado en la base de datos como un objeto de la propia base y puede ser llamado, como se llamaría a cualquier otro método.

#### Llamar a un Procedimiento Almacenado desde JDBC

JDBC permite llamar a un procedimiento almacenado en la base de datos desde una aplicación escrita en Java. El primer paso es crear un objeto CallableStatement. Al igual que con los objetos Statement y PreparedStatement, esto se hace con una conexión abierta, Connection. Un objeto CallableStatement contiene una llamada a un procedimiento almacenado; no contiene el propio procedimiento. La primera línea del código siguiente crea una llamada al procedimiento almacenado SHOW_SUPPLIERS utilizando la conexión con. La parte que está encerrada entre corchetes es la sintaxis de escape para los precedimientos almacenados. Cuando un controlador encuentra "{call SHOW_SUPPLIERS}", traducirá esta sintaxis de escape al SQL nativo utilizado en la base de datos para llamar al procedimiento almacenado llamado SHOW_SUPPLIERS:

    CallableStatement cs = con.prepareCall("{call SHOW_SUPPLIERS}");
    ResultSet rs = cs.executeQuery();

La hoja de resultados de rs será similar a esto:

    SUP_NAME			COF_NAME
    ----------------		-----------------------
    Acme, Inc.			Colombian
    Acme, Inc.			Colombian_Decaf
    Superior Coffee			French_Roast
    Superior Coffee			French_Roast_Decaf
    The High Ground			Espresso

Observa que el método utilizado para ejecutar cs es executeQuery porque cs llama a un procedimiento almacenado que contiene una petición y esto produce una hoja de resultados. Si el procedimiento hubiera contenido una sentencia de actualziación o una sentencia DDL, se hubiera utilizado el método executeUpdate. Sin embargo, en algunos casos, cuando el procedimiento almacenado contiene más de una sentencia SQL producirá más de una hoja de resultados, o cuando contiene más de una cuenta de actualizaciónm o alguna combinación de hojas de resultados y actualizaciones. en estos casos, donde existen múltiples resultados, se debería utilizar el método execute para ejecutar CallableStatement.

La clase CallableStatement es una subclase de PreparedStatement, por eso un objeto CallableStatement puede tomar parámetros de entrada como lo haría un objeto PreparedStatement. Además, un objeto CallableStatement puede tomar parámetros de salida, o parámetros que son tanto de entrada como de salida. Los parámetros INOUT y el método execute se utilizan raramente.

Ozito