Middle
Como chamar um procedimento armazenado em Java?
sobes.tech IA
Resposta da IA
Para chamar um procedimento armazenado em Java, utiliza-se CallableStatement do pacote java.sql.
Passos principais:
- Obter a conexão: Usa-se um objeto
Connection.// Exemplo de obtenção de conexão (depende do driver e configuração) Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/mydatabase", "user", "password"); - Criar
CallableStatement: A chamada SQL ao procedimento armazenado é passada ao construtorprepareCall(). A sintaxe depende do SGBD, mas geralmente tem a forma{ call procedure_name(?, ?, ...) }.// Chamada de procedimento sem parâmetros CallableStatement cstmt = conn.prepareCall("{ call my_procedure() }"); // Chamada de procedimento com parâmetros CallableStatement cstmtWithParams = conn.prepareCall("{ call my_procedure_with_params(?, ?) }"); - Definir os parâmetros de entrada: Se o procedimento aceita parâmetros, eles devem ser definidos usando os métodos
setXxx(), ondeXxxcorresponde ao tipo de dado (por exemplo,setString,setInt).// Definir parâmetros de entrada cstmtWithParams.setString(1, "value1"); cstmtWithParams.setInt(2, 123); - Registar os parâmetros de saída (se houver): Se o procedimento devolve valores através de parâmetros de saída, eles devem ser registados com
registerOutParameter(), indicando o índice e o tipo de dado JDBC.// Procedimento com parâmetro de saída CallableStatement cstmtWithOut = conn.prepareCall("{ call my_procedure_with_out(?) }"); cstmtWithOut.registerOutParameter(1, Types.VARCHAR); // VARCHAR como exemplo - Executar a consulta: Usa-se o método
execute(). Se o procedimento devolve um conjunto de resultados, pode-se usarexecuteQuery().// Executar procedimento cstmt.execute(); // Para procedimentos sem conjunto de resultados // Executar procedimento que devolve um conjunto de resultados // CallableStatement cstmtWithResultSet = conn.prepareCall("{ call get_data() }"); // ResultSet rs = cstmtWithResultSet.executeQuery(); - Processar os resultados: Se o procedimento devolve um conjunto de resultados, pode-se processar como um
ResultSetnormal. Se houver parâmetros de saída, os seus valores são extraídos com métodosgetXxx().// Processar parâmetro de saída String result = cstmtWithOut.getString(1); // Processar conjunto de resultados /* while (rs.next()) { // Ler dados do conjunto de resultados } rs.close(); */ - Fechar recursos: É importante fechar
CallableStatementeConnection. É recomendável usar blocostry-with-resources.// Fechamento de recursos usando try-with-resources try (Connection conn = DriverManager.getConnection("...", "...", "...")) { try (CallableStatement cstmt = conn.prepareCall("{ call my_procedure(?) }")) { cstmt.setString(1, "test"); cstmt.execute(); // Processar resultados } } catch (SQLException e) { e.printStackTrace(); }
Exemplo de chamada de procedimento com valor de entrada e valor retornado (via RETURN, e não um parâmetro OUT, característico no PostgreSQL/MySQL):
// Procedimento na base de dados: CREATE OR REPLACE FUNCTION add_numbers(a INT, b INT) RETURNS INT AS $$ BEGIN RETURN a + b; END; $$ LANGUAGE plpgsql;
try (Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/mydatabase", "user", "password")) {
// Chamada de função SQL (frequentemente usa-se a sintaxe { ? = call function_name(?, ?) } para funções)
try (CallableStatement cstmt = conn.prepareCall("{ ? = call add_numbers(?, ?) }")) {
// Registar parâmetro de retorno
cstmt.registerOutParameter(1, Types.INTEGER);
// Definir parâmetros de entrada
cstmt.setInt(2, 10);
cstmt.setInt(3, 20);
// Executar a chamada
cstmt.execute();
// Obter o resultado
int sum = cstmt.getInt(1);
System.out.println("Soma: " + sum); // Saída: Soma: 30
}
} catch (SQLException e) {
e.printStackTrace();
}
Diferenças entre CallableStatement e PreparedStatement:
| Característica | PreparedStatement |
CallableStatement |
|---|---|---|
| Propósito | Executar consultas SQL parametrizadas | Chamar procedimentos e funções armazenadas |
| Sintaxe | Consulta SQL com ? |
Sintaxe dialetal de chamada ({ CALL ... }) |
| Parâmetros de saída | Não (apenas conjunto de resultados) | Sim (via registerOutParameter) |
| Valor retornado | Apenas conjunto de resultados (executeQuery) |
Pode ser via RETURN (como parâmetro OUT), conjunto de resultados |
É necessário verificar a sintaxe de chamada de procedimentos/funções armazenadas ({ call ... } ou outro) e o suporte de tipos de dados JDBC (Types) para o SGBD específico utilizado.