Cómo llamar a procedimientos almacenados usando JAVA
El método getByte toma un byte de Java del primer parámetro OUT y getBigDecimal toma un objeto BigDecimal (tres dígitos después del punto decimal) del segundo parámetro OUT: declaración invocable cstmt = con prepare call(" { call gettest data( ?, ?)}");
cstmt.registeroutparameter(1,Java.SQL.types.tinyint);
cstmt.registerOutParameter(2,java.sql.Types.DECIMAL, 3 );
cs TMT . ejecutar consulta();
byte x = cstmt . . getbigdecimal(2, 3); A diferencia de ResultSet, CallableStatement no proporciona un mecanismo especial para recuperar valores OUT grandes de forma incremental. 3. Los parámetros INOUT admiten parámetros de entrada y salida (parámetros INOUT). Además de llamar al método RegisterOutParameter, también debe llamar al método setXXX apropiado (heredado de PreparedStatement). El método setXXX establece el valor del parámetro como parámetro de entrada, mientras que el método RegisterOutParameter registra su tipo JDBC como parámetro de salida. El método setXXX proporciona un valor Java. El controlador primero convierte este valor en un valor JDBC y luego lo envía a la base de datos. El tipo JDBC de este valor IN debe ser el mismo que el tipo proporcionado al método RegisterOutParameter. Luego, para recuperar el valor de salida, se debe utilizar el método getXXX correspondiente. Por ejemplo, un parámetro de tipo Java byte debe utilizar el método setByte para asignar el valor de entrada. RegisterOutParameter debe proporcionarse con JDBC tipo TINYINT y getByte debe usarse para recuperar el valor de salida. El siguiente ejemplo supone un procedimiento almacenado revisarTotal cuyo único parámetro es el parámetro INOUT. El método setByte establece este parámetro en 25, que el controlador envía a la base de datos como un tipo JDBC TINYINT. A continuación, RegisterOutParameter registra el parámetro como JDBC TINYINT. Después de ejecutar el procedimiento almacenado, se devolverá un nuevo valor JDBC TINYINT. El método getByte recupera este nuevo valor como un tipo de byte Java. declaración invocable cstmt = con . prepare call(" { llamar a revisar total(?)}");
cstmt.setByte(1, 25); Java . SQL tipos . tinyint);
cs TMT .ejecute update(); luego obtenga byte(1); recuperar parámetros de salida. Debido a ciertas limitaciones de DBMS, para máxima portabilidad, se recomienda recuperar primero los resultados generados al ejecutar el objeto CallableStatement y luego usar el método CallableStatement.getXXX para recuperar los parámetros OUT.
Si el objeto CallableStatement devuelve varios objetos ResultSet (llamando al método de ejecución), se deben recuperar todos los resultados antes de recuperar los parámetros OUT. En este caso, para garantizar que se haya accedido a todos los resultados, se deben llamar a los métodos de declaración getResultSet, getUpdateCount y getMoreResults hasta que no haya más resultados. Una vez recuperados todos los resultados, el valor del parámetro OUT se puede recuperar utilizando el método CallableStatement.getXXX. 5. Recupere el valor NULL como parámetro OUT. El valor devuelto al parámetro OUT puede ser JDBC NULL. Cuando esto sucede, los valores nulos de JDBC se convierten para que el valor devuelto por el método getXXX sea NULL, 0 o falso, según el tipo de método getXXX. Para los objetos ResultSet, la única forma de saber si 0 o false se originó en JDBCNULL es detectar utilizando el método wasNull. Si el último valor leído por el método getXXX es JDBC NULL, el método devuelve verdadero; de lo contrario, devuelve falso.
Valores de retorno complejos Mucha gente parece estar familiarizada con el conocimiento sobre procedimientos almacenados. Si eso es todo lo que puede hacer un procedimiento almacenado, entonces los procedimientos almacenados no sustituyen a otros mecanismos de ejecución remota. Los procedimientos almacenados son mucho más poderosos que esto.
Algunos DBMS permiten que un procedimiento almacenado devuelva una referencia a un cursor. JDBC no admite esta función, pero todos los controladores JDBC para Oracle, PostgreSQL y DB2 admiten la apertura de un puntero al cursor en el conjunto de resultados.
Imagínate hacer una lista de todos los poetas que no llegaron a la edad de jubilación. El siguiente es el procedimiento almacenado que completa esta función, que devuelve un cursor abierto y también utiliza el lenguaje pl/pgsql de PostgreSQL: crear lista de procedimientos _ muertes tempranas() devolver el cursor de referencia como ' declarar los dedos de los pies arriba el cursor de referencia comenzar con selecciones El poeta; se abre. nombre, muerte. Era del poeta, Muerte: todas las entradas de Muerte son para el poeta. - pero la tabla puede volverse genérica. donde poets.id = death.mort_id and death.age lt60; return toesup end; 'language "plpgsql" Aquí está el método Java que llama al procedimiento almacenado y envía el resultado a PrintWriter:
PrintWriter: static void senderalydeaths(PrintWriter out){ Conexión con = null; CallableStatement toesUp = null por favor intente { con = grupo de conexiones. obtener conexión() // PostgreSQL requiere una transacción para completar este trabajo... con . ) ; //Crear una llamada. declaración invocable para sup = conexión preparar llamada ({? = lista de llamadas _ muertes tempranas ()} "; dedo sup . registro de parámetro (1, tipo.
Otros); toe sup. ejecutar(); ResultSet RS = (ResultSet) para sup. getobject(1); 2); out.println(nombre "tiene" edad "años."); } RS . close(); catch (SQLException e) { //Debemos proteger estas llamadas. toe sup . close(); con . close() }} Debido a que JDBC no admite directamente la devolución de cursores desde procedimientos almacenados, utilizamos el tipo. OTHER para indicar el tipo de retorno del procedimiento almacenado y luego llame al método getObject() para convertir el valor de retorno.
Este método Java que llama a un procedimiento almacenado es un buen ejemplo de mapeo. El mapeo es una forma de realizar operaciones abstractas en colecciones. En este proceso, podemos enviar operaciones a realizar en lugar de devolver una colección. En este caso, la operación consiste en imprimir el conjunto de resultados en el flujo de salida. Este es un ejemplo muy común que vale la pena dar. Aquí hay otra forma de llamar al mismo procedimiento almacenado: clase pública Processpoedays {public abstract void send death(String name, Intage); static void mapEarlyDeaths(processpoeddeaths mapper) { Connection con = null; grupo de conexiones. obtener conexión(); con. establecer auto commit(false); instrucción invocable en sup = conexión. preparar llamada ({?= lista de llamadas _ muertes tempranas()} "toe sup. registro de parámetro (1, tipo). ); toe sup . ejecutar(); ResultSet RS = (ResultSet) para sup . getobject(1); ); mapper.sendDeath(nombre, edad); } RS . close(); } catch (SQLException e) { // Deberíamos proteger estas llamadas toe close(); procesamiento de los datos del conjunto de resultados No es necesario cambiar o duplicar el método para obtener el conjunto de resultados: static void sendearly deaths(impresión final) { Processpoeddeaths my mapper = new Processpoeddeaths() { public void send death(String name, int). edad) { out.println(nombre "es" edad "años"); } }; mapEarlyDeaths(mi mapeador } Este método llama a mapEarlyDeaths usando una instancia anónima de ProcessPoetDeaths.
Esta instancia tiene una implementación del método sendDeath, que escribe los resultados en el flujo de salida de la misma manera que en el ejemplo anterior. Por supuesto, esta técnica no es exclusiva de los procedimientos almacenados, pero cuando se combina con el conjunto de resultados devuelto en un procedimiento almacenado, es una herramienta muy poderosa. Conclusión Los procedimientos almacenados le ayudan a separar la lógica de su código, lo que básicamente siempre es un beneficio. Los beneficios de esta separación son:
Cree aplicaciones rápidamente y utilice un esquema de base de datos que cambia y mejora con la aplicación.
El esquema de la base de datos se puede cambiar en el futuro sin afectar a los objetos Java. Cuando terminemos la aplicación, podremos rediseñarla con un mejor esquema.
Los procedimientos almacenados hacen que el SQL complejo sea más fácil de entender mediante una mejor integración de SQL.
Existen mejores herramientas para escribir procedimientos almacenados en Java que para escribir SQL incorporado: ¡la mayoría de los editores ofrecen resaltado de sintaxis!
Los procedimientos almacenados se pueden probar en cualquier línea de comando SQL, lo que facilita la depuración. No todas las bases de datos admiten procedimientos almacenados, pero existen muchas implementaciones excelentes, tanto gratuitas/de código abierto como no libres, por lo que la portabilidad no es un problema. Oracle, PostgreSQL y DB2 tienen lenguajes de procedimientos almacenados similares que cuentan con el respaldo de la comunidad en línea.
Existen muchas herramientas para procedimientos almacenados, incluidos editores, depuradores e IDE como TOAD o TORA, que proporcionan un entorno potente para escribir y mantener PL/SQL o pl/pgsql.
Los procedimientos almacenados añaden coste a su código, pero son mucho más baratos que la mayoría de los servidores de aplicaciones.