
- •Формирование запросов к базе данных.
- •Множественные операции
- •Order by
- •For update of
- •Последовательности
- •Фразы оператора select
- •Фраза from
- •Фразы group by и having
- •Фраза having
- •Фраза where
- •Фраза where (Встроенный sql)
- •Фраза current of
- •Фразы connect by и start with
- •Start with
- •Использование order by
- •Фраза order by
- •Внешнее объединение
- •Подзапросы.
- •Функции агрегирования результатов запроса
- •Курсоры
- •Види курсоров
- •Объявление курсора.
- •Открытие курсора
- •Атрибуты курсора.
- •Чтение данных с использованием курсора.
- •Закрытие курсора
- •Неявные курсоры. Предопределенный курсор sql.
- •Примеры работы с курсорами
- •Изменение и удаление данных в позиции курсора.
- •Переменные-курсоры.
- •Работа с транзакциями в pl/sql.
- •Курсоры и транзакции.
Переменные-курсоры.
Переменная-курсор является ссылкой на набор данных, возвращаемых запросом. В отличие от обычного курсора, который однозначно определяет набор данных, переменная-курсор может указывать на различные наборы данных в разные моменты времени. Несколько таких переменных могут ссылаться на один и тот же набор данных. Такие переменные можно передавать от клиента серверу, работать с ними как с параметрами процедур и функций. Переменные-курсоры не смешиваются с обычными (статическими) курсорами: нельзя использовать одни там, где ожидаются другие и наоборот.
Описание переменной-курсора производится за два шага.
1. Сначала описывается тип переменной:
TYPE имя-типа-курсора IS REF CURSOR [RETURN тип-возврата];
Имя-типа-курсора в дальнейшем будет использоваться при описании конкретных переменных. Тип-возврата должен быть записью, типом строки в таблице базы данных или типом строки другого курсора. Если RETURN присутствует, то такой тип называется сильным (ограничивающим) - его можно связывать только с запросами, возвращающими строку такого же типа, если RETURN не указано, то тип будет слабым (неограничивающим) и будет совместим с любым запросом.
Примеры:
DECLARE
TYPE EC_type IS REF CURSOR
RETURN Employee%ROWTYPE;
TYPE GC_type IS REF CURSOR;
Переменная-курсор первого типа (EC_type) может указывать только на запросы, возвращающие строку таблицы Employee.
Вместо Employee%ROWTYPE может стоять имя-типа-другого-курсора%ROWTYPE, где имя-типа-другого-курсора было описано ранее аналогичным образом.
2. Описывается переменная соответствующего типа (в разделе объявлений).
Для предыдущего примера можно написать:
DECLARE
emp_cv EC_type;
После этого данной переменной можно ставить в соответствие различные запросы. Это делается с помощью оператора OPEN...FOR так:
OPEN имя-переменной FOR select-оператор;
OPEN emp_cv FOR SELECT * FROM Employee;
Такой запрос не может быть FOR UPDATE.
Дальнейшая работа с переменной-курсором аналогична работе с обычным курсором. Данные читаются оператором FETCH:
DECLARE emp_rec EC_type%ROWTYPE;
...
FETCH emp_cv INTO emp_rec;
При этом нельзя использовать цикл FOR.
Если тип переменной, в которую читаются данные по FETCH, не совпадает с типом курсора, генерируется исключительная ситуация ROWTYPE_MISMATCH.
Если переменная не открыта, то будет ошибка INVALID_CURSOR.
Переменные-курсоры можно присваивать друг другу. Если один курсор был открыт, то другой после присваивания тоже станет открытым. Если типы возврата не совпадают - ROWTYPE_MISMATCH.
Работа с транзакциями в pl/sql.
В PL/SQL допустимы стандартные операторы обработки транзакций COMMIT и ROLLBACK. Можно устанавливать промежуточные точки по SAVEPOINT. Следует отметить, что транзакции не зависят от блоков PL/SQL и могут начинаться в одном блоке, а заканчиваться в другом.
Курсоры и транзакции.
Специальные псевдоколонки ROWID и ROWNUM.
Если выполнить COMMIT в середине цикла, работающего с курсором, объявленным как FOR UPDATE, то блокировки будут сняты и далее работать с таким курсором нельзя. Если нужно закрывать транзакцию в середине такого цикла, то курсор не объявляют FOR UPDATE, а используют для ссылки на последнюю считанную запись псевдоколонку ROWID.
ROWID в Oracle - это псевдоколонка, которая уникальным образом идентифицирует строку таблицы базы данных. Это двоичное значение, которое можно перевести в 18-байтную строку. На нее можно ссылаться, например, при изменении или удалении данных как на последнюю строку,выбранную из курсора. Вот пример:
DECLARE
CURSOR c1 IS SELECT emp_name, salary, rowid FROM Employee;
...
FOR emp_rec IN c1 LOOP
EXIT WHEN c1%NOTFOUND;
IF ... THEN
DELETE FROM emp WHERE rowid = emp_rec.rowid;
COMMIT;
END IF;
END LOOP;
Таким образом можно работать в цикле с такими курсорами, не обращая внимание на транзакции.
Наряду с ROWID в Oracle есть колонка ROWNUM, которая отражает порядок, в котором запись была выбрана из таблицы - для первой колонки 1, для второй 2 и т.д. Основное применение - ограничить число записей, возвращаемых запросом:
SELECT * FROM Employee WHERE ROWNUM < 100;
вернет первые 100 записей.