Sobes.tech
Middle

Как да извикаме съхранена процедура в Java?

sobes.tech AI

Отговор от AI

За извикване на съхранена процедура в Java се използва CallableStatement от пакета java.sql.

Основните стъпки:

  1. Получаване на връзка: Използва се обектът Connection.
    // Пример за получаване на връзка (зависи от драйвера и конфигурацията)
    Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/mydatabase", "user", "password");
    
  2. Създаване на CallableStatement: SQL-извикването на съхранена процедура се предава в конструктора prepareCall(). Синтаксисът зависи от СУБД, но често има вид { call procedure_name(?, ?, ...) }.
    // Извикване на процедура без параметри
    CallableStatement cstmt = conn.prepareCall("{ call my_procedure() }");
    
    // Извикване на процедура с параметри
    CallableStatement cstmtWithParams = conn.prepareCall("{ call my_procedure_with_params(?, ?) }");
    
  3. Задаване на входни параметри: Ако процедурата приема параметри, те трябва да бъдат зададени чрез методите setXxx(), където Xxx съответства на типа данни (например, setString, setInt).
    // Задаване на входни параметри
    cstmtWithParams.setString(1, "value1");
    cstmtWithParams.setInt(2, 123);
    
  4. Регистриране на изходни параметри (ако има): Ако процедурата връща стойности чрез изходни параметри, те трябва да бъдат регистрирани с registerOutParameter(), като се посочи индексът на параметъра и типът данни JDBC.
    // Процедура с изходен параметър
    CallableStatement cstmtWithOut = conn.prepareCall("{ call my_procedure_with_out(?) }");
    cstmtWithOut.registerOutParameter(1, Types.VARCHAR); // VARCHAR като пример
    
  5. Изпълнение на заявката: Използва се методът execute(). Ако процедурата връща резултатен набор, може да се използва executeQuery().
    // Изпълнение на процедура
    cstmt.execute(); // За процедури без резултатен набор
    
    // Изпълнение на процедура, която връща резултатен набор
    // CallableStatement cstmtWithResultSet = conn.prepareCall("{ call get_data() }");
    // ResultSet rs = cstmtWithResultSet.executeQuery();
    
  6. Обработка на резултатите: Ако процедурата връща резултатен набор, той може да бъде обработен като обикновен ResultSet. Ако има изходни параметри, техните стойности се извличат с getXxx().
    // Обработка на изходен параметър
    String result = cstmtWithOut.getString(1);
    
    // Обработка на резултатен набор
    /*
    while (rs.next()) {
        // Четене на данни от резултатния набор
    }
    rs.close();
    */
    
  7. Затваряне на ресурсите: Важно е да се затворят 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) за конкретната използвана СУБД.