Usar un procedimiento almacenado con parámetros de salida

Un procedimiento almacenado de SQL Server al que se puede llamar es el que devuelve uno o más parámetros OUT, que son los parámetros que el procedimiento almacenado usa para devolver los datos a la aplicación que realiza la llamada. El controlador JDBC de Microsoft SQL Server ofrece la clase SQLServerCallableStatement, que puede usar para llamar a este tipo de procedimiento almacenado y procesar los datos que devuelve.

Cuando se llama a este tipo de procedimiento almacenado con el controlador JDBC, se debe usar la secuencia de escape de SQL call junto con el método prepareCall de la clase SQLServerConnection. La sintaxis para la secuencia de escape call con parámetros OUT es la siguiente:

{call procedure-name[([parameter][,[parameter]]...)]}

Nota

Para obtener más información acerca de las secuencias de escape de SQL, consulte Usar secuencias de escape SQL.

Al crear la secuencia de escape call, especifique los parámetros OUT mediante el carácter ? (signo de interrogación). Este carácter actúa como un marcador de posición para los valores de parámetros devueltos por el procedimiento almacenado. Para especificar un valor para un parámetro OUT, debe especificar el tipo de datos de cada parámetro mediante el método registerOutParameter de la clase SQLServerCallableStatement antes de ejecutar el procedimiento almacenado.

El valor especificado para el parámetro OUT en el método registerOutParameter debe ser uno de los tipos de datos JDBC incluidos en java.sql.Types, que se asigna a su vez a uno de los tipos de datos de SQL Server nativos. Para obtener más información acerca de los tipos de datos JDBC y de SQL Server, consulte Describir los tipos de datos del controlador JDBC.

Cuando pasa un valor al método registerOutParameter para un parámetro OUT, debe especificar no solo los tipos de datos usados para el parámetro, sino también la posición ordinal del parámetro o el nombre del mismo en el procedimiento almacenado. Por ejemplo, si el procedimiento almacenado contiene un solo parámetro OUT, su valor ordinal es 1 y, si el procedimiento almacenado contiene dos parámetros, el primer valor ordinal es 1 y el segundo 2.

Nota

El controlador JDBC no admite el uso de los tipos de datos CURSOR, SQLVARIANT, TABLE y TIMESTAMP SQL Server como parámetros OUT.

Cree, a modo de ejemplo, el siguiente procedimiento almacenado en la base de datos de ejemplo AdventureWorks de SQL Server 2005:

CREATE PROCEDURE GetImmediateManager
   @employeeID INT,
   @managerID INT OUTPUT
AS
BEGIN
   SELECT @managerID = ManagerID 
   FROM HumanResources.Employee 
   WHERE EmployeeID = @employeeID
END

Este procedimiento almacenado devuelve un solo parámetro OUT (managerID), que es un entero, en función del parámetro IN (employeeID) especificado, que también es un entero. El valor devuelto en el parámetro OUT es ManagerID en función de EmployeeID en la tabla HumanResources.Employee.

En el siguiente ejemplo, se pasa una conexión abierta a la base de datos de ejemplo AdventureWorks a la función y se usa el método execute para llamar al procedimiento almacenado GetImmediateManager:

public static void executeStoredProcedure(Connection con) {
   try {
      CallableStatement cstmt = con.prepareCall("{call dbo.GetImmediateManager(?, ?)}");
      cstmt.setInt(1, 5);
      cstmt.registerOutParameter(2, java.sql.Types.INTEGER);
      cstmt.execute();
      System.out.println("MANAGER ID: " + cstmt.getInt(2));
   }
   catch (Exception e) {
      e.printStackTrace();
   }
}

Este ejemplo utiliza las posiciones ordinales para identificar los parámetros. También puede identificar un parámetro utilizando su nombre en lugar de su posición ordinal. En el ejemplo de código siguiente se modifica el ejemplo anterior para demostrar cómo utilizar los parámetros con nombre en una aplicación Java. Observe que los nombres de parámetros se corresponden con los nombres de parámetros en la definición del procedimiento almacenado:

public static void executeStoredProcedure(Connection con) {
   try {
      CallableStatement cstmt = con.prepareCall("{call dbo.GetImmediateManager(?, ?)}");
      cstmt.setInt("employeeID", 5);
      cstmt.registerOutParameter("managerID", java.sql.Types.INTEGER);
      cstmt.execute();
      System.out.println("MANAGER ID: " + cstmt.getInt("managerID"));
      cstmt.close();
   }
   catch (Exception e) {
      e.printStackTrace();
   }

}

Nota

En estos ejemplos se usa el método execute de la clase SQLServerCallableStatement para ejecutar el procedimiento almacenado. Se usa dicho método porque el procedimiento almacenado no ha devuelto ningún conjunto de resultados. En caso contrario, se usaría el método executeQuery.

Los procedimientos almacenados también pueden devolver recuentos de actualizaciones y múltiples conjuntos de resultados. El controlador JDBC de Microsoft SQL Server sigue la especificación de JDBC 3.0, que indica que se deben recuperar varios conjuntos de resultados y actualizaciones antes de que se recuperen los parámetros OUT. Es decir, la aplicación debería recuperar todos los objetos ResultSet y recuentos de actualizaciones antes de recuperar los parámetros OUT con los métodos CallableStatement.getter. De lo contrario, los objetos ResultSet y recuentos de actualizaciones que aún no se hayan recuperado se perderán cuando se recuperen los parámetros OUT. Para obtener más información acerca de los recuentos de actualizaciones y los conjuntos de resultados múltiples, vea Usar un procedimiento almacenado con un recuento de actualizaciones y Usar múltiples conjuntos de resultados.

Vea también

Otros recursos

Usar instrucciones con procedimientos almacenados