Java вызов хранимых процедур

JDBC: CallableStatement

Java.sql.CallableStatement используется для вызова хранимых процедур в базе данных.

Хранимая процедура похожа на функцию или метод в классе, за исключением того, что она находится в базе данных. Некоторые тяжелые операции с базой данных могут выиграть в производительности от выполнения в том же пространстве памяти, что и сервер базы данных, в качестве хранимой процедуры.

Создание CallableStatement

Вы создаете экземпляр CallableStatement, вызывая метод prepareCall() для объекта подключения. Вот пример:

CallableStatement callableStatement = connection.prepareCall("");

Если хранимая процедура возвращает ResultSet, и вам нужен ResultSet не по умолчанию(например, с другими характеристиками удерживаемости, параллелизма и т. Д.), Вам нужно будет указать эти характеристики уже при создании CallableStatement. Вот пример:

CallableStatement callableStatement = connection.prepareCall("", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_OVER_COMMIT );

Установка значений параметров

После создания CallableStatement очень похож на PreparedStatement. Например, вы можете установить параметры в SQL, в тех местах, где вы ставите? , Вот пример:

CallableStatement callableStatement = connection.prepareCall(""); callableStatement.setString(1, "param1"); callableStatement.setInt (2, 123);

Выполнение CallableStatement

После того, как вы установили значения параметров, которые вам нужно установить, вы готовы выполнить CallableStatement. Вот как это делается:

ResultSet result = callableStatement.executeQuery();

Метод executeQuery() используется, если хранимая процедура возвращает ResultSet.

Если хранимая процедура просто обновляет базу данных, вы можете вместо этого вызвать метод executeUpdate(), например:

callableStatement.executeUpdate();

Пакетные обновления

Вы можете сгруппировать несколько вызовов хранимой процедуры в пакетное обновление. Вот как это делается:

CallableStatement callableStatement = connection.prepareCall(""); callableStatement.setString(1, "param1"); callableStatement.setInt (2, 123); callableStatement.addBatch(); callableStatement.setString(1, "param2"); callableStatement.setInt (2, 456); callableStatement.addBatch(); int[] updateCounts = callableStatement.executeBatch();

Параметры OUT

Хранимая процедура может возвращать параметры OUT. То есть значения, которые возвращаются вместо ResultSet или в дополнение к нему. После выполнения CallableStatement вы можете получить доступ к этим параметрам OUT из объекта CallableStatement. Вот пример:

CallableStatement callableStatement = connection.prepareCall(""); callableStatement.setString(1, "param1"); callableStatement.setInt (2, 123); callableStatement.registerOutParameter(1, java.sql.Types.VARCHAR); callableStatement.registerOutParameter(2, java.sql.Types.INTEGER); ResultSet result = callableStatement.executeQuery(); while(result.next()) < . >String out1 = callableStatement.getString(1); int out2 = callableStatement.getInt (2);

Рекомендуется сначала обработать ResultSet, прежде чем пытаться получить доступ к любым параметрам OUT. Это рекомендуется по причинам совместимости базы данных.

Источник

Вызов функций SQL-сервера

У JDBC есть еще один интерфейс для еще более сложных сценариев. Он унаследован от PreparedStatement и называется CallableStatement .

Он используется для вызова (Call) хранимых процедур в базе данных. Особенность такого вызова в том, что кроме результата ResultSet такой хранимой процедуре можно еще и передать параметры.

А что тут нового, спросишь ты? PreparedStatement тоже имеет результат ResultSet и в него тоже можно передавать параметры. Да, все верно, но особенность хранимых процедур в том, что через параметры они могут не только получать, но и возвращать данные.

Хранимая процедура вызывается с параметрами IN, OUT и INOUT. Она возвращает один или несколько объектов ResultSet . Для создания объекта CallableStatement предназначен метод Connection.prepareCall() .

Вот представь, что у тебя есть хранимая процедура ADD, которая принимает параметры a, b и c. Эта процедура складывает a и b и помещает результат сложения в переменную с.

Давай напишем код, где попробуем ее вызвать:

 // Подключение к серверу Connection connection = DriverManager.getConnection("jdbc:as400://mySystem"); // Создание объекта CallableStatement. Он выполняет предварительную обработку // вызова хранимой процедуры. Знаки вопроса // указывают, где должны быть подставлены входные параметры, а где выходные // Первые два параметра являются входными, // а третий — выходным. CallableStatement statement = connection.prepareCall("CALL MYLIBRARY.ADD (?, ?, ?)"); // Настройка входных параметров. Передаем в процедуру 123 и 234 statement.setInt (1, 123); statement.setInt (2, 234); // Регистрация типа выходного параметра statement.registerOutParameter (3, Types.INTEGER); // Запуск хранимой процедуры statement.execute(); // Получение значения выходного параметра int sum = statement.getInt(3); // Закрытие CallableStatement и Connection statement.close(); connection.close(); 

Работа почти как с PreparedStatement , только есть нюанс. Наша функция ADD возвращает в третьем параметре результат сложения. Только вот объект CallableStatement об этом ничего не знает. Поэтому мы говорим ему об это явно, вызвав метод registerOutParameter() :

 registerOutParameter(номерПараметра, типПараметра)

После этого можно вызывать процедуру через метод execute() и затем читать данные из третьего параметра с помощью методa getInt() .

Batching запросов

В реальных проектах часто возникает ситуация, когда необходимо сделать очень много однотипных запросов (наиболее часто в этом случае встречается PreparedStatement ), например, надо вставить несколько десятков или сотен записей.

Если выполнять каждый запрос отдельно, то это займет кучу времени и снизит производительность приложения. Чтобы не допустить этого, можно использовать batch-режим вставки. Он заключается в том, что ты накапливаешь некоторый буфер своими запросами, а потом выполняешь их сразу.

В качестве примера приведу кусочек кода:

 PreparedStatement stmt = con.prepareStatement( "INSERT INTO jc_contact (first_name, last_name, phone, email) VALUES (?, ?, ?, ?)"); for (int i = 0; i < 10; i++) < // Заполняем параметры запроса stmt.setString(1, "FirstName_" + i); stmt.setString(2, "LastNAme_" + i); stmt.setString(3, "phone_" + i); stmt.setString(4, "email_" + i); // Запрос не выполняется, а укладывается в буфер, // который потом выполняется сразу для всех команд stmt.addBatch(); >// Выполняем все запросы разом int[] results = stmt.executeBatch(); 

Вместо того, чтобы выполнять запрос методом execute() , мы складываем его в пакет с помощью метода addBatch() .

А затем, когда набралось несколько сотен запросов, можно их разом отправить на сервер, вызвав команду executeBatch() .

Полезно. Метод executeBatch() возвращает массив целых чисел — int[]. Каждая ячейка этого массива содержит число, которое означает количество строк, измененных соответствующим запросом. Если запрос номер 3 в batch’е изменил 5 строк, то 3-я ячейка массива будет содержать число 5.

Источник

Читайте также:  Python selenium горячие клавиши
Оцените статью