Middle
Как да извикаме съхранена процедура в Java?
sobes.tech AI
Отговор от AI
За извикване на съхранена процедура в Java се използва CallableStatement от пакета java.sql.
Основните стъпки:
- Получаване на връзка: Използва се обектът
Connection.// Пример за получаване на връзка (зависи от драйвера и конфигурацията) Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/mydatabase", "user", "password"); - Създаване на
CallableStatement: SQL-извикването на съхранена процедура се предава в конструктораprepareCall(). Синтаксисът зависи от СУБД, но често има вид{ call procedure_name(?, ?, ...) }.// Извикване на процедура без параметри CallableStatement cstmt = conn.prepareCall("{ call my_procedure() }"); // Извикване на процедура с параметри CallableStatement cstmtWithParams = conn.prepareCall("{ call my_procedure_with_params(?, ?) }"); - Задаване на входни параметри: Ако процедурата приема параметри, те трябва да бъдат зададени чрез методите
setXxx(), къдетоXxxсъответства на типа данни (например,setString,setInt).// Задаване на входни параметри cstmtWithParams.setString(1, "value1"); cstmtWithParams.setInt(2, 123); - Регистриране на изходни параметри (ако има): Ако процедурата връща стойности чрез изходни параметри, те трябва да бъдат регистрирани с
registerOutParameter(), като се посочи индексът на параметъра и типът данни JDBC.// Процедура с изходен параметър CallableStatement cstmtWithOut = conn.prepareCall("{ call my_procedure_with_out(?) }"); cstmtWithOut.registerOutParameter(1, Types.VARCHAR); // VARCHAR като пример - Изпълнение на заявката: Използва се методът
execute(). Ако процедурата връща резултатен набор, може да се използваexecuteQuery().// Изпълнение на процедура cstmt.execute(); // За процедури без резултатен набор // Изпълнение на процедура, която връща резултатен набор // CallableStatement cstmtWithResultSet = conn.prepareCall("{ call get_data() }"); // ResultSet rs = cstmtWithResultSet.executeQuery(); - Обработка на резултатите: Ако процедурата връща резултатен набор, той може да бъде обработен като обикновен
ResultSet. Ако има изходни параметри, техните стойности се извличат сgetXxx().// Обработка на изходен параметър String result = cstmtWithOut.getString(1); // Обработка на резултатен набор /* while (rs.next()) { // Четене на данни от резултатния набор } rs.close(); */ - Затваряне на ресурсите: Важно е да се затворят
CallableStatementиConnection. По-добре е да се използва блокtry-with-resources.// Затваряне на ресурси с използване на try-with-resources try (Connection conn = DriverManager.getConnection("...", "...", "...")) { try (CallableStatement cstmt = conn.prepareCall("{ call my_procedure(?) }")) { cstmt.setString(1, "test"); cstmt.execute(); // Обработка на резултатите } } catch (SQLException e) { e.printStackTrace(); }
Пример за извикване на процедура с входни и връщащи стойности (чрез RETURN, а не OUT-параметър, характерно за PostgreSQL/MySQL):
// Процедура в базата данни: 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")) {
// SQL-извикване на функция (често се използва синтаксис { ? = call function_name(?, ?) } за функции)
try (CallableStatement cstmt = conn.prepareCall("{ ? = call add_numbers(?, ?) }")) {
// Регистриране на изходния параметър (връщаната стойност)
cstmt.registerOutParameter(1, Types.INTEGER);
// Задаване на входните параметри
cstmt.setInt(2, 10);
cstmt.setInt(3, 20);
// Изпълнение на извикването
cstmt.execute();
// Получаване на резултата
int sum = cstmt.getInt(1);
System.out.println("Сума: " + sum); // Изход: Сума: 30
}
} catch (SQLException e) {
e.printStackTrace();
}
Разликите между CallableStatement и PreparedStatement:
| Особеност | PreparedStatement |
CallableStatement |
|---|---|---|
| Назначение | Изпълнение на параметризирани SQL-заявки | Извикване на съхранени процедури и функции |
| Синтаксис | SQL-заявка с ? |
Диалектен синтаксис за извикване ({ CALL ... }) |
| Изходни параметри | Няма (само резултатен набор) | Има (чрез registerOutParameter) |
| Връщана стойност | Само резултатен набор (executeQuery) |
Може да бъде чрез RETURN (като OUT-параметър), резултатен набор |
Необходимо е да се провери синтаксисът за извикване на съхранени процедури/функции ({ call ... } или друг) и поддръжката на типове данни JDBC (Types) за конкретната използвана СУБД.