Empleo de un procedimiento almacenado con parámetros de salida
Un procedimiento almacenado de SQL Server al que se puede llamar es aquel 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 para SQL Server ofrece la clase SQLServerCallableStatement, que se 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 JDBC Driver, se debe usar la secuencia de escape call
de SQL junto con el método prepareCall de la clase SQLServerConnection. Para la secuencia de escape call
sin parámetros OUT, la sintaxis es la siguiente:
{call procedure-name[([parameter][,[parameter]]...)]}
Nota:
Para obtener más información sobre las secuencias de escape de SQL, consulte Usar secuencias de escape de SQL.
Al crear la secuencia de escape call
, especifique los parámetros OUT mediante el carácter del 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 nativos de SQL Server. Para obtener más información sobre el JDBC y los tipos de datos de SQL Server, consulte Comprender los tipos de datos del controlador JDBC.
Cuando pasa un valor al método registerOutParameter para un parámetro OUT, debe especificar no solo el tipo de datos que se usará 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. Si el procedimiento almacenado contiene dos parámetros, el primer valor ordinal es 1 y el segundo 2.
Nota:
JDBC Driver no admite el uso de los tipos de datos CURSOR, SQLVARIANT, TABLE y TIMESTAMP de SQL Server como parámetros OUT.
Cree, a modo de ejemplo, el siguiente procedimiento almacenado en la base de datos de ejemplo AdventureWorks2022:
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 a la función una conexión abierta a la base de datos de ejemplo AdventureWorks2022 y se usa el método execute para llamar al procedimiento almacenado GetImmediateManager:
public static void executeStoredProcedure(Connection con) throws SQLException {
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));
}
}
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. 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) throws SQLException {
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"));
}
}
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 para SQL Server sigue la especificación de JDBC 3.0, que indica que se deben recuperar varios conjuntos de resultados y recuentos de actualizaciones antes de recuperar 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 los recuentos de actualizaciones que el controlador aún no haya recuperado se perderán cuando se recuperen los parámetros OUT. Para obtener más información sobre los recuentos de actualizaciones y varios conjuntos de resultados, consulte Empleo de un procedimiento almacenado con un recuento de actualización y Empleo de varios conjuntos de resultados.