JDBC Procedimientos almacenados

Usando el controlador JDBC para tener acceso a un servidor ya sea SQL Server o MYSQL podemos llamar a procedimientos almacenados, estos son funciones que están alojadas en la propia base de datos y que podemos llamar como si fuesen funciones o procedimientos de cualquier otro lenguaje de programación.

Llamar a un procedimiento almacenado sin parámetros


La forma mas simple de un procedimiento almacenado el aquella que no necesita parámetros de entrada y que solamente devuelve un conjunto de datos, como si fuese una consulta SQL que usamos normalmente.

Para el ejemplo he agregado el siguiente procedimiento almacenado a la base de datos:

DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `simple`()
BEGIN
 select * from city;
END$$
DELIMITER ;

Para llamar a este procedimiento almacenado hacemos lo siguiente:

Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("{call sakila.simple}");

while (rs.next()) {
       System.out.println(rs.getString("city"));
}

rs.close();
stmt.close();

{call sakila.simple} usamos call para llamar al procedimiento, sakila es el nombre de la base de datos y simple es el nombre del procedimiento que deseamos ejecutar.

Ejecutar procedimiento almacenado con datos de entrada y salida


Si deseamos llamar a un procedimiento almacenado y este necesita parámetros de entrada podemos especificarlos con el signo de interrogación ( ? ), luego indicar cada parámetro con el método apropiado, de este modo: 

Para este ejemplo usaremos el procedimiento film_in_stock que ya viene en la base de datos que estamos usando de ejemplo, este necesita dos parámetros int de entrada de devuelve un int de salida: 

DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `film_in_stock`(IN p_film_id INT, IN p_store_id INT, OUT p_film_count INT)
    READS SQL DATA
BEGIN
     SELECT inventory_id
     FROM inventory
     WHERE film_id = p_film_id
     AND store_id = p_store_id
     AND inventory_in_stock(inventory_id);

     SELECT FOUND_ROWS() INTO p_film_count;
END$$
DELIMITER ;

Código para ejecutar este procedimiento almacenado:

CallableStatement cstmt =  connection.prepareCall("{call sakila.film_in_stock(?, ?, ?)}");
            
cstmt.setInt("p_film_id", 19);
cstmt.setInt("p_store_id", 1);
cstmt.registerOutParameter("p_film_count", java.sql.Types.INTEGER);
            
cstmt.execute();
            
System.out.println(cstmt.getInt("p_film_count"));
            
cstmt.close();

cstmt.setInt establece los parámetros de entrada para el tipo int debemos indicar el nombre del parámetro y el valor.

cstmt.registerOutParameter establece el parámetro de salida, indicamos el nombre seguido de el tipo de datos que devuelve.

En el caso de que el procedimiento almacenado que deseamos ejecutar no devolviera ningún valor especifico si no que devuelve un conjunto de datos como en el caso de un procedimiento simple como el primer ejemplo, pero necesitáramos indicar un valor de entrada podemos hacerlo de este modo:

PreparedStatement pstmt = con.prepareStatement("{call database.storedprocedure(?)}");
pstmt.setInt(1, 50);
ResultSet rs = pstmt.executeQuery();

Descargar Procedimientos Almacenados JDBC

Comentarios

  1. Estimado:

    Tengo el un procedimiento almacenado que ejecutado así "EXEC [dbo].[SP_GET_INSUMOS_PROGRAMA] '20140812' " desde SQL Server corre perfectamente, pero llamándolo de java no hace nada. Podrías decirme donde puede estar el error?

    String connectionUrl = "jdbc:sqlserver://localhost:1433;" + "databaseName=SUCEDA;user=sa; password=sa;";

    Connection con = null;

    try {

    Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");

    con = DriverManager.getConnection(connectionUrl);

    con.setAutoCommit(false);

    } catch (SQLException ex) {

    Logger.getLogger(PlanProduccionf.class.getName()).log(Level.SEVERE, null, ex);

    } catch (ClassNotFoundException ex) {

    Logger.getLogger(PlanProduccionf.class.getName()).log(Level.SEVERE, null, ex);

    }

    try {

    CallableStatement cStmt = con.prepareCall("{call dbo.SP_GET_INSUMOS_PROGRAMA(?)}");

    Date utilDate = new Date();

    java.sql.Date Fecha = new java.sql.Date(utilDate.getTime());

    cStmt.setDate(1,null );

    JOptionPane.showMessageDialog(null, "Comezar a ejecutar MRP ...");

    cStmt.execute();

    final ResultSet rs = cStmt.getResultSet();

    JOptionPane.showMessageDialog(null, "Proceso ejecutado ");//Indicamos al usuario que el proceso fue exitoso...

    } catch (SQLException ex) {

    Logger.getLogger(PlanProduccionf.class.getName()).log(Level.SEVERE, null, ex);

    }

    ResponderEliminar
    Respuestas
    1. cStmt.setDate(1,null ); aquí podría estar el posible error, indica una fecha valida en lugar de null.
      tambien debes registrar el parametro llamando a la funcion de registro de este modo:
      cStmt.registerOutParameter(1, java.sql.Types.DATE);

      Eliminar

Publicar un comentario

Entradas populares de este blog

Conectar SQL Server con Java

Entrenar OpenCV en Detección de Objetos

Procesamiento de imágenes en OpenCV

Acceso a la webcam con OpenCV

Conociendo la clase cv::Mat de OpenCV