13

Prepared statement

Embed Size (px)

Citation preview

Page 1: Prepared statement
Page 2: Prepared statement

PREPAREDSTATEMENT:

DEFINICIÓN:

El PreparedStatement nos permite definir una sentencia SQL base, que nos sirve para modificar/insertar/buscar uno o varios registros con sólo cambiar los valores de los parámetros que especifiquemos. La definición de PreparedStatement es una sentencia SQL precompilada para ser ejecutada muchas veces. Pero al crear el PreparedStatement cada vez, se está precompilando y ejecutando. Perdiendo completamente la ventaja en rendimiento que supone el precompilado de una sentencia SQL. Hay algunos manejadores que inclusive crean un procedimiento almacenado temporal, cada vez que se crea un PreparedStatement.

Page 3: Prepared statement

La interfaz PreparedStatement hereda de Statement y difiere de esta en dos maneras.

Las instancias de PreparedStatement contienen

una sentencia SQL que ya ha sido compilada.

Esto es lo que hace que se le llame ‘preparada’.

La sentencia SQL contenida en un

objeto PreparedStatement pueden tener uno o

más parámetros IN. Un parámetro IN es aquel

cuyo valor no se especifica en la sentencia SQL

cuando se crea.

En vez de ello la sentencia tiene un interrogante como

un ‘ancla’ para cada parámetro IN. Debes suministrar un

valor para cada interrogante mediante el método

apropiado, que puede ser: setInt, setString, etc, antes

de ejecutar la sentencia creada por el método

PreparedStatement, un objeto de este tipo se usa para

sentencias SQL que se toman uno o más parámetros

como argumentos de entrada.

Page 4: Prepared statement

Son muy útiles cuando una sentencia SQL se ejecuta muchas veces cambiando solo de algunos valores.

Se utiliza para enviar sentencias SQL precompiladas con uno o más parámetros.

Se crea un objeto PreparedStatement especificando la plantilla y los lugares donde irán.

Prepared Statement tiene un grupo de métodos que fijan los valores de los parámetros IN, los cuales son enviados

a la base de datos cuando se procesa la sentencia SQL. Las instancias del preparedStatement se extienden, es

decir heredan del Statement y por tanto heredan los métodos de Statement. Un objeto PreparedStatement es

potencialmente más eficiente que un objeto Statement porque este ha sido precompilado y almacenado para su

uso futuro.

Page 5: Prepared statement

MÉTODO EXECUTEUPDATE():

Ejecuta la instrucción SQL determinada, que puede ser una instrucción INSERT, UPDATE o DELETE; o una instrucción SQL que no devuelve nada, como una instrucción DDL de SQL. Desde

el controlador JDBC 3.0 de MicrosoftSQL Server,

executeUpdate devolverán el número correcto de filas

actualizado en una operación MERGE.

Sintaxis: public int executeUpdate(java.lang.String

sql) .

Page 6: Prepared statement

Un objeto CallableStatement provee de una forma estándar de llamar a procedimientos almacenados de la base de

datos. Un procedimiento almacenado se encuentra en la base de datos. La llamada al procedimiento es lo que

contiene el objeto CallableStatement. Esta llamada se escribe en una sintaxis de escape que puede tomar una de

dos formas: un formato con un parámetro resultado y el otro sin él. Un parámetro resultado, un tipo de parámetro

OUT, es el valor devuelto por el procedimiento almacenado. Ambos formatos pueden tener un número variable de

parámetros de entrada (parámetros IN), de salida (parámetros OUT) o ámbos (parámetros INOUT). Un interrogante

sirve como ‘anclaje’ para cada parámetro.

USO DE CALLABLESTATEMENT:

Page 7: Prepared statement

Crear objetos

CallableStatement:

Los objetos CallableStatement se crean con el método prepareCall de Connection. El siguiente ejemplo crea una instancia de CallableStatement que contiene una llamada al procedimiento almacenado getTestData, con dos argumentos y no devuelve resultados.

CallableStatement cstmt =

con.prepareCall("{call

getTestData(?, ?)}");

Donde los encajes ‘?’ son parámetros IN, OUT ó INOUT dependiendo del

procedimiento getTestData.

Parámetros IN y OUT:

El paso de valor para cualquier parámetro

IN de un objeto CallableStatement se realiza mediante los

métodos setXXX heredados de

PreparedStatement. El tipo del valor a

pasar se determina por el método setXXX a usar

(setFloat para pasar un valor float, y así).

Page 8: Prepared statement

Para ilustrar esto, el siguiente ejemplo registra los parámetros OUT, ejecuta el procedimiento almacenado llamado por cstmt y recupera los valores devueltos en los parámetros OUT. El método getByte recupera un byte Java del

primer parámetro, y getBigDecimal recupera un objeto BigDecimal (con tres dígitos después del punto decimal) del segundo parámetro OUT:

En otras palabras, registerOutParameter usa un tipoJDBC (por tanto, coincide con el tipo con el tipo JDBC que la base de datos devolverá) y getXXX ‘casts’ este a un

tipo Java.

Si el procedimiento almacenado devuelve parámetros OUT, el tipo JDBC de cada parámetro OUT debe ser registrado antes de que el objeto CallableStatement sea ejecutado (Esto es necesario porque algunas DBMS necesitan el tipo JDBC). El registro del tipo JDBC se realiza mediante el método registerOutParameters. Después que la sentencia ha sido ejecutada, los métodos getXXX de CallableStatement recuperan los valores de los parámetros. El método correcto getXXX a usar es el tipo Java que corresponde al tipo JDBC registrado para el parámetro.

Page 9: Prepared statement

CallableStatement cstmt = con.prepareCall(

"{call getTestData(?, ?)}");cstmt.registerOutParameter(1,

java.sql.Types.TINYINT);cstmt.registerOutParameter(2, java.sql.Types.DECIMAL, 3);

cstmt.executeQuery();byte x = cstmt.getByte(1);java.math.BigDecimal n = cstmt.getBigDecimal(2, 3);

De modo distinto a ResultSet,

CallableStatement no tiene un mecanismo

especial para recuperar grandes valores OUT

incrementalmente.

Parámetros INOUT:

Son parámetros que suministran entradas así como aceptan

salidas. Estos requieren llamar a los métodos apropiados setXXX

(heredados de PreparedStatement) además de

llamar al método registerOutParameter. Los

métodos setXXX fijan los valores como parámetros de entrada y

registerOutParameter registra sus tipos JDBC como parámetros de

salida. El método setXXX suminstra un valor Java que el

driver convierte en un valor JDBC antes de enviarlo a la base de

datos.

Page 10: Prepared statement

El tipo JDBC del valor IN y el tipo JDBC para suminstrado al método registerOutParameter debe ser el mismo. Luego, para recuperar el valor de salida, se usa el método apropiado

getXXX. Por ejemplo, un parámetro cuyo tipo Java es byte debería usar el método setByte para asignar el valor de entrada, debería suplir un TINYINT como tipo JDBC para

registerOutParameter, y debería usar getByte para recuperar el valor de salida (Sección 8, da más información y contiene tablas de tipos mapeados).

El siguiente ejemplo asume que existe un procedimiento almacenado reviseTotal con un único parámetro INOUT. El método setByte fija el valor del parámetro a 25 que es el que el

driver enviará a la base de datos como un JDBC TINYINT. Después registerOutParameter registrará el parámetro como un JDBC TINYINT. Luego que el procedimiento sea ejecutado

se devolverá un nuevo JDBC TINYINT y el método getByte lo recuperará como un nuevo valor byte Java.

CallableStatement cstmt = con.prepareCall("{call reviseTotal(?)}");cstmt.setByte(1, 25);

cstmt.registerOutParameter(1, java.sql.Types.TINYINT);cstmt.executeUpdate();

byte x = cstmt.getByte(1);

Page 11: Prepared statement

Recuperar parámetros OUT después de resultados.

Dadas las limitaciones impuestas por algunas DBMS, se recomienda en aras de la máxima portabilidad, que todos los resultados generados por la ejecución de un objeto CallableStatement deberían recuperarse antes que los parámetros OUT usando los métodos CallableStatement.getXXX.

Si un objeto CallableStatement devuelve múltiples objetos ResultSet (mediante una llamada al método execute), todos los resultados deben recuperarse antes que los parámetros OUT. En este caso, debe asegurarse de que todos los resultados han sido accedidos, los métodos de Statement getResultSet, getUpdateCount y getMoreResults necesitan ser llamados hasta que no haya más resultados.

Después de hecho esto, los valores de los parámetros OUT pueden ser recuperados mediante los métodos CallableStatement.getXXX.

Recuperar valores NULL en parámetros OUT:

El valor devuelto en un parámetro OUT puede ser JDBC NULL. Cuando esto ocurre, le valor JDBC NULL se convertirá de forma que el valor devuelto por el método getXXX sea null, 0 o false dependiendo del tipo del método getXXX usado. Como con los objetos ResultSet, la única manera de saber si un valor de 0 o false fue originalmente NULL JDBC es testear el método wasNull, que devuelve true si el último valor leído por un método getXXX fue JDBC NULL y false en caso contrario. La sección 5 contiene más información al respecto.

Page 12: Prepared statement

EJEMPLO:Un ejemplo típico es:

PreparedStatement pstmt = con.prepareStatement("update empleado set sueldo = ? where id_empleado = ?");pstmt.setDouble(1, 153833.00);pstmt.setInt(2, 110592);

Esto nos permite tener una sentencia SQL de fácil lectura y sin tener que concatenar cadenas o hacer conversiones de

tipos. De la documentación de java:

Objeto que representa una instrucción SQL precompilada. Una instrucción SQL se precompila y se almacena en un objeto

PreparedStatement. Este objeto puede utilizarse para ejecutar esta sentencia de forma eficiente varias veces.Supongamos que tenemos un mapa de empleados y sueldos:

Map<Integer, Double> empleadoSueldo = new HashMap<>();empleadoSueldo.put(1, 1000.0);empleadoSueldo.put(2, 2000.0);empleadoSueldo.put(3, 3000.0);

Page 13: Prepared statement

Ejemplo de PreparedStatement de consulta:Por ejemplo, supongamos que hay un campo de texto en el que el usuario puede introducir su dirección de correo electrónico y con este dato se desea buscar al usuario:

Connection con = DriverManager.getConnection(url);String consulta = "SELECT usuario FROM registro WHERE email like ?";PreparedStatement pstmt = con.prepareStatement(consulta);pstmt.setString(1 , campoTexto.getText());ResultSet resultado = ps.executeQuery();

Ejemplo de PreparedStatement de modificación:En el siguiente ejemplo se va a insertar un nuevo registro en una tabla:

Connection con = DriverManager.getConnection(url);String insercion = "INSERT INTO registro(usuario , email , fechaNac) values ( ? , ? , ? )");PreparedStatement pstmt = con.prepareStatement(consulta);String user = . . . ;String email = . . . ;Date edad = . . . ; //O int edad;pstmt.setString(1 , user);pstmt.setString(2 , email);pstmt.setDate(3 , edad); // setInt(3, edad);ps.executeUpdate();