- •Работа с субд PostgreSql
- •Работа с субд PostgreSql
- •Введение
- •1Установка PostgreSql
- •2Создание новой бд
- •2.1Создание новой бд
- •2.2Создание новой таблицы
- •2.3Создание связей между таблицами
- •3Создание индексов
- •4Доступ к PostgreSql из Java
- •4.1Соединение с PostgreSql
- •4.2Взаимодействие с бд
- •5Создание представлений
- •6Хранимые процедуры и Триггеры
- •6.1Хранимые процедуры
- •6.1.1Оператор Create Function языка pl/pgSql
- •6.1.2Создание хранимых процедур в pgAdmin III
- •6.1.3Вызов хранимых процедур в Java
- •6.2Триггеры бд
- •6.2.1Синтаксис определения триггера в PostgreSql
- •6.2.2Создание триггера в PgAdmin III
- •7Права доступа
- •Создание ролей;
- •7.1Создание ролей
- •7.2Назначение прав доступа
- •7.3Отмена прав доступа
- •7.4Проверка прав доступа
- •8Резервное копирование и восстановление бд
- •8.1Резервное копирование (BackUp) бд
- •8.2Восстановление (Restore) бд
- •8.3Создание sql-дампа бд
- •8.4Восстановление sql-дампа бд
- •8.5Восстановление sql-дампа средствами pgAdmin III
- •9Особенности взаимодействия субд access и PostgreSql
- •9.1Подготовка соединения PostgreSql с бд в Access
- •9.2Копирование таблиц Access в таблицы PostgreSql
- •9.3Подключение таблиц PostgreSql к бд в Access
- •10Администрирование PostgreSql
- •Литература
6.1.2Создание хранимых процедур в pgAdmin III
Рассмотрим процесс создания хранимой процедуры (функции) в pgAdmin III для примера 3, описанного выше.
Ниже приведено описание способа создания функции.
В окне Браузер объектов для определенной БД выбирается раздел Функции, активизируется его контекстное меню, в котором выбирается пункт Новая функция (рисунок 6.1).
Рисунок 6.1 – Контекстное меню Функции
В открывшемся окне Новая функция на закладке Свойства (рисунок 6.2) необходимо указать:
Имя – имя новой функции, которое должно быть уникальным среди имен функций схемы БД;
Владелец – владелец функции;
Тип возврата – тип результата, который возвращает функция;
Язык – процедурный язык, на котором описывается функция;
Временность – VOLATILE [7] указывает на то, что значение функции может изменяться в пределах одного сканирования таблицы (используется по умолчанию);
Возвращает множество – выбирается в том случае, если функция возвращает множественный результат.
На закладке Параметры (рисунок 6.3) определяются параметры, передаваемые в функцию. Для добавления параметра необходимо указать его тип (свойство Тип аргумента), выбрать режим (In, Out, In/Out), задать имя.
На закладке Определение (рисунок 6.4) вводятся операторы основного программного блока функции, а также, если необходимо, секция определений. После определения функции необходимо нажать кнопку ОК.
Рисунок 6.2 – Закладка Свойства окна Новая функция
Рисунок 6.3 – Закладка Параметры окна Новая функция
Рисунок 6.4 – Закладка Определение окна Новая функция
Для выполнения функции в PostgreSQL используется оператор SELECT. Например,
select * from public."getStudGroup"('КС-042');
Проверить работу созданной функции можно выполнив пользовательский SQL запрос (рисунок 6.5).
Рисунок 6.5 – Результат работы функции
6.1.3Вызов хранимых процедур в Java
Вызов хранимых процедур из Java приложения практически ничем не отличается от выполнения обычного SQL запроса на выборку данных. Интеграция с JDBC – это огромное достоинство для хранимых процедур, поскольку для того, чтобы ее вызывать из приложения, не нужно изменять классы или использовать какие либо конфигурационные файлы.
JDBC поддерживает вызов хранимых процедур с помощью класса CallableStatement. Этот класс является подклассом класса PreparedStatement. Строка, которая подается в качестве параметра методу prepareCall() – это спецификация вызова процедуры. Она определяет имя вызываемой процедуры и символы ‘?’, которые определяют необходимые параметры. Возможны два варианта спецификации. Если функция:
Возвращает значение
{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
Не возвращает значение
{call <procedure-name>[(<arg1>,<arg2>, ...)]}
При выполнении хранимых процедур возможно возникновение ошибочных ситуаций, в этом случае будет сгенерировано исключение SQLException.
Рассмотрим варианты вызова хранимых процедур, приведенных в пункте 5.1.1.
Пример 1. Функция c несколькими входными параметрами и не возвращает значений: Добавить сведения о новом студенте: insStudent(st_no integer, st_name character varying)
connection.setAutoCommit(false); CallableStatement proc = connection.prepareCall("{call insStudent( ? , ? ) }"); proc.setInt(1, 958977); proc.setString(2, "Иванов"); proc.execute();
|
В этой функции используется два параметра. Для присвоения параметрам значений используются методы setInt(1, 958977) для задания значения типа int первому параметру и setString(2, "Иванов") для задания значения типа String второму параметру.
Пример 2. Функция не имеет входных параметров и возвращает одно значение: Подсчитать сумму затрат на стипендию всех студентов — getSumStipAll().
connection.setAutoCommit(false); CallableStatement proc = connection.prepareCall("{ ? = call getSumStipAll() }"); proc.registerOutParameter(1, Types.REAL); proc.execute(); float sum = proc.getFloat(1); |
С помощью метода registerOutParameter() регистрируется SQL-тип выходного параметра. В Java вместо типа real используется тип float, и поэтому для получения результата функции используется метод getFloat().
Пример 3. Функция с одним входным параметром и возвращает одно значение: Подсчитать сумму затрат на стипендию всех студентов группы Х, где Х – параметр, задающий название группы: getStipGroup(gr_name character varying)
connection.setAutoCommit(false); CallableStatement proc = connection.prepareCall("{ ? = call getStipGroup(?) }"); proc.registerOutParameter(1, Types.REAL); proc.setString(2, "КС-071"); proc.execute(); float sum = proc.getFloat(1); |
В этой функции используется один параметр. Для его задания используется метод setString(2, "КС-071"), где значение 2 указывает, что второму параметру хранимой процедуры, т.е. первому параметру функции getStipGroup необходимо присвоить строковое значение.
Пример 4. Функция с одним входным параметром и возвращает множество элементов (записей) таблицы: getStudGroup(gr_name character varying).
connection.setAutoCommit(false); CallableStatement proc = connection.prepareCall("{ ? = call getStudGroup(?) }"); proc.registerOutParameter(1, Types.OTHER); proc.setString(2, "КС-071"); proc.execute();
ResultSet rs = (ResultSet) proc.getObject(1); while (rs.next()){ String name = rs.getString(3); float stip = proc.getFloat(4); System.out.println("Cтудент " + name + " стипендия " + stip); } rs.close(); |
Результатом этой функции является множество строк из таблицы Student. Множество строк представляется объектом класса ResultSet. С помощью метода registerOutParameter(1, Types.OTHER) регистрируется тип выходного параметра как Types.OTHER. В Java для хранения объектов этого типа используется класс Object. После вызова хранимой процедуры необходимо произвести нисходящее преобразование к типу ResultSet. Далее используется стандартный способ обхода записей объекта ResultSet.