El autor de este artículo presenta cómo llamar a los procedimientos almacenados de SQL Server a través de Java y explica en detalle cinco tipos diferentes de almacenamiento. Consulte a continuación para obtener más detalles.
1. Utilice un procedimiento almacenado sin parámetros.
Cuando utilice un controlador JDBC para llamar a un procedimiento almacenado sin parámetros, debe utilizar la secuencia de escape SQL de llamada. La sintaxis de la secuencia de escape de llamadas sin parámetros es la siguiente:
Copie el código de código de la siguiente manera:
{nombre-procedimiento de llamada}
Como ejemplo, cree el siguiente procedimiento almacenado en la base de datos de ejemplo de SQL Server 2005 AdventureWorks:
Copie el código de código de la siguiente manera:
CREAR PROCEDIMIENTO GetContactFormalNames
COMO
COMENZAR
SELECCIONE LOS 10 PRINCIPALES Título + ' ' + Nombre + ' ' + Apellido COMO Nombre Formal
DE Persona.Contacto
FIN
Este procedimiento almacenado devuelve un único conjunto de resultados que contiene una columna de datos que consta del título, nombre y apellido de los primeros diez contactos en la tabla Person.Contact.
En el siguiente ejemplo, a esta función se le pasa una conexión abierta a la base de datos de ejemplo AdventureWorks y luego se llama al procedimiento almacenado GetContactFormalNames mediante el método ejecutarQuery.
Copie el código de código de la siguiente manera:
public static void ejecutarSprocNoParams(Conexión con) ...{
intentar...{
Declaración stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("{call dbo.GetContactFormalNames}");
mientras (rs.siguiente()) ...{
System.out.println(rs.getString("Nombreformal"));
}
rs.cerrar();
stmt.close();
}
captura (Excepción e) ...{
e.printStackTrace();
}
}
2. Utilice un procedimiento almacenado con parámetros de entrada.
Cuando utilice un controlador JDBC para llamar a un procedimiento almacenado con parámetros, debe utilizar la secuencia de escape SQL de llamada junto con el método prepareCall de la clase SQLServerConnection. La sintaxis para una secuencia de escape de llamada con un parámetro IN es la siguiente:
Copie el código de código de la siguiente manera:
{llamar nombre-procedimiento[([parámetro][,[parámetro]]...)]}
Al construir una secuencia de escape de llamada, utilice el carácter ? (signo de interrogación) para especificar el parámetro IN. Este carácter sirve como marcador de posición para el valor del parámetro que se pasará al procedimiento almacenado. Puede utilizar uno de los métodos de establecimiento de la clase SQLServerPreparedStatement para especificar valores para los parámetros. Los métodos de configuración disponibles están determinados por el tipo de datos del parámetro IN.
Al pasar un valor a un método de establecimiento, debe especificar no solo el valor real que se utilizará en el parámetro, sino también la posición ordinal del parámetro dentro del procedimiento almacenado. Por ejemplo, si un procedimiento almacenado contiene un único parámetro IN, su valor ordinal es 1. Si el procedimiento almacenado contiene dos parámetros, el primer valor ordinal es 1 y el segundo valor ordinal es 2.
Como ejemplo de cómo llamar a un procedimiento almacenado que contiene un parámetro IN, utilice el procedimiento almacenado uspGetEmployeeManagers en la base de datos de ejemplo AdventureWorks de SQL Server 2005. Este procedimiento almacenado acepta un único parámetro de entrada denominado EmployeeID, que es un valor entero, y devuelve una lista recursiva de empleados y sus gerentes según el EmployeeID especificado. Aquí está el código Java que llama a este procedimiento almacenado:
Copie el código de código de la siguiente manera:
public static void ejecutarSprocInParams(Conexión con) ...{
intentar...{
PreparedStatement pstmt = con.prepareStatement("{call dbo.uspGetEmployeeManagers(?)}");
pstmt.setInt(1, 50);
Conjunto de resultados rs = pstmt.executeQuery();
mientras (rs.siguiente()) ...{
System.out.println("EMPLEADO:");
System.out.println(rs.getString("Apellido") + ", " + rs.getString("Nombre"));
System.out.println("ADMINISTRADOR:");
System.out.println(rs.getString("ManagerLastName") + ", " + rs.getString("ManagerFirstName"));
System.out.println();
}
rs.cerrar();
pstmt.close();
}
captura (Excepción e) ...{
e.printStackTrace();
}
}
3. Utilice un procedimiento almacenado con parámetros de salida.
Al llamar a dichos procedimientos almacenados mediante un controlador JDBC, debe utilizar la secuencia de escape SQL de llamada junto con el método prepareCall de la clase SQLServerConnection. La sintaxis de una secuencia de escape de llamada con un parámetro OUT es la siguiente:
Copie el código de código de la siguiente manera:
{llamar nombre-procedimiento[([parámetro][,[parámetro]]...)]}
Al construir una secuencia de escape de llamada, utilice el carácter ? (signo de interrogación) para especificar el parámetro OUT. Este carácter sirve como marcador de posición para el valor del parámetro que devolverá este procedimiento almacenado. Para especificar valores para los parámetros OUT, debe utilizar el método RegisterOutParameter de la clase SQLServerCallableStatement para especificar el tipo de datos de cada parámetro antes de ejecutar el procedimiento almacenado.
El valor especificado para el parámetro OUT mediante el método RegisterOutParameter debe ser uno de los tipos de datos JDBC contenidos en java.sql.Types, que a su vez se asigna a uno de los tipos de datos nativos de SQL Server. Para obtener más información sobre los tipos de datos JDBC y SQL Server, consulte Descripción de los tipos de datos del controlador JDBC.
Cuando pasa un valor al método RegisterOutParameter para un parámetro OUT, no solo debe especificar el tipo de datos que se usará para el parámetro, sino que también debe especificar la posición ordinal del parámetro o el nombre del parámetro en el procedimiento almacenado. Por ejemplo, si un procedimiento almacenado contiene un único parámetro OUT, su valor ordinal es 1; si un procedimiento almacenado contiene dos parámetros, el primer valor ordinal es 1 y el segundo valor ordinal es 2.
Como ejemplo, cree el siguiente procedimiento almacenado en la base de datos de ejemplo AdventureWorks de SQL Server 2005: Según el parámetro IN de entero especificado (ID de empleado), este procedimiento almacenado también devuelve un parámetro OUT de entero único (ID de administrador). Según el EmployeeID contenido en la tabla HumanResources.Employee, el valor devuelto en el parámetro OUT es ManagerID.
En el siguiente ejemplo, a esta función se le pasa una conexión abierta a la base de datos de ejemplo AdventureWorks y luego se llama al procedimiento almacenado GetImmediateManager mediante el método de ejecución:
Copie el código de código de la siguiente manera:
public static void ejecutarStoredProcedure (Conexión con) ...{
intentar...{
CallableStatement cstmt = con.prepareCall("{call dbo.GetImmediateManager(?, ?)}");
cstmt.setInt(1, 5);
cstmt.registerOutParameter(2, java.sql.Types.INTEGER);
cstmt.execute();
System.out.println("ID DE ADMINISTRADOR: " + cstmt.getInt(2));
}
captura (Excepción e) ...{
e.printStackTrace();
}
}
Este ejemplo utiliza la posición ordinal para identificar parámetros. Alternativamente, el parámetro se puede identificar por su nombre en lugar de por su posición ordinal. El siguiente ejemplo de código modifica el ejemplo anterior para ilustrar cómo utilizar parámetros con nombre en una aplicación Java. Tenga en cuenta que estos nombres de parámetros corresponden a los nombres de parámetros en la definición del procedimiento almacenado: 11x16CREATE PROCEDURE GetImmediateManager
Copie el código de código de la siguiente manera:
@employeeID INT,
@managerID ENTRADA SALIDA
COMO
COMENZAR
SELECCIONAR @managerID = ManagerID
DE Recursos Humanos.Empleado
DONDE ID de empleado = @ID de empleado
FIN
Los procedimientos almacenados pueden devolver recuentos de actualizaciones y múltiples conjuntos de resultados. El controlador JDBC de Microsoft SQL Server 2005 cumple con la especificación JDBC 3.0, que establece que se deben recuperar múltiples conjuntos de resultados y recuentos de actualizaciones antes de recuperar los parámetros OUT. Es decir, la aplicación primero debe recuperar todos los objetos ResultSet y actualizar el recuento, y luego usar el método CallableStatement.getter para recuperar los parámetros OUT. De lo contrario, cuando se recupere el parámetro OUT, se perderán el objeto ResultSet y el recuento de actualizaciones que aún no se han recuperado.
4. Utilice procedimientos almacenados con estado de devolución.
Al llamar a un procedimiento almacenado de este tipo mediante un controlador JDBC, debe utilizar la secuencia de escape SQL de llamada junto con el método prepareCall de la clase SQLServerConnection. La sintaxis de una secuencia de escape de llamada que devuelve un parámetro de estado es la siguiente:
Copie el código de código de la siguiente manera:
{[?=]llamar nombre-procedimiento[([parámetro][,[parámetro]]...)]}
Al construir una secuencia de escape de llamada, utilice el carácter ? (signo de interrogación) para especificar el parámetro de estado de devolución. Este carácter sirve como marcador de posición para el valor del parámetro que devolverá este procedimiento almacenado. Para especificar un valor para un parámetro de estado de devolución, debe especificar el tipo de datos del parámetro utilizando el método RegisterOutParameter de la clase SQLServerCallableStatement antes de ejecutar el procedimiento almacenado.
Además, al pasar el valor del parámetro de estado de retorno al método RegisterOutParameter, debe especificar no solo el tipo de datos del parámetro que se utilizará, sino también la posición ordinal del parámetro en el procedimiento almacenado. La posición ordinal del parámetro de estado de retorno es siempre 1 porque siempre es el primer parámetro cuando se llama al procedimiento almacenado. Aunque la clase SQLServerCallableStatement admite el uso del nombre del parámetro para indicar un parámetro específico, solo puede usar el número de posición ordinal del parámetro para devolver parámetros de estado.
Como ejemplo, cree el siguiente procedimiento almacenado en la base de datos de ejemplo de SQL Server 2005 AdventureWorks:
Copie el código de código de la siguiente manera:
CREAR PROCEDIMIENTO CheckContactCity
(@ciudadNombre CHAR(50))
COMO
COMENZAR
SI ((SELECCIONAR CUENTA(*)
DE Persona.Dirección
DONDE Ciudad = @nombredeciudad) > 1)
VOLVER 1
DEMÁS
VOLVER 0
FIN
El procedimiento almacenado devuelve un valor de estado de 1 o 0, dependiendo de si la ciudad especificada por el parámetro cityName se puede encontrar en la tabla Person.Address.
En el siguiente ejemplo, a esta función se le pasa una conexión abierta a la base de datos de ejemplo AdventureWorks y luego se llama al procedimiento almacenado CheckContactCity mediante el método de ejecución:
Copie el código de código de la siguiente manera:
public static void ejecutarStoredProcedure (Conexión con) ...{
intentar...{
CallableStatement cstmt = con.prepareCall("{? = llamar a dbo.CheckContactCity(?)}");
cstmt.registerOutParameter(1, java.sql.Types.INTEGER);
cstmt.setString(2, "Atlanta");
cstmt.execute();
System.out.println("ESTADO DE DEVOLUCIÓN: " + cstmt.getInt(1));
}
cstmt.close();
captura (Excepción e) ...{
e.printStackTrace();
}
}
5. Utilice un procedimiento almacenado con un recuento de actualizaciones.
Después de usar la clase SQLServerCallableStatement para construir una llamada a un procedimiento almacenado, puede usar los métodos ejecutar o ejecutarUpdate para llamar al procedimiento almacenado. El método ejecutarUpdate devuelve un valor int que contiene el número de filas afectadas por este procedimiento almacenado, pero el método de ejecución no devuelve este valor. Si utiliza el método de ejecución y desea obtener un recuento del número de filas afectadas, puede llamar al método getUpdateCount después de ejecutar el procedimiento almacenado.
Como ejemplo, cree las siguientes tablas y procedimientos almacenados en la base de datos de ejemplo de SQL Server 2005 AdventureWorks:
Copie el código de código de la siguiente manera:
CREAR TABLA Tabla de pruebas
(Col1 int IDENTIDAD,
Col2varchar(50),
Col3 int);
CREAR PROCEDIMIENTO UpdateTestTable
@Col2varchar(50),
@Col3 entero
COMO
COMENZAR
ACTUALIZAR tabla de pruebas
ESTABLECER Col2 = @Col2, Col3 = @Col3
FIN;
En el siguiente ejemplo, a esta función se le pasa una conexión abierta a la base de datos de ejemplo AdventureWorks, usa el método de ejecución para llamar al procedimiento almacenado UpdateTestTable y luego usa el método getUpdateCount para devolver el recuento de filas afectadas por el procedimiento almacenado.
Copie el código de código de la siguiente manera:
public static void ejecutarUpdateStoredProcedure (Conexión con) ...{
intentar...{
CallableStatement cstmt = con.prepareCall("{call dbo.UpdateTestTable(?, ?)}");
cstmt.setString(1, "A");
cstmt.setInt(2, 100);
cstmt.execute();
int recuento = cstmt.getUpdateCount();
cstmt.close();
System.out.println("FILAS AFECTADAS: " + recuento);
}
captura (Excepción e) ...{
e.printStackTrace();