Объявление курсора и работа с ним
Курсором называют переменную, объявляемую в приложении и со- держащую отклик на запрос. Курсор является интерфейсом, который пере- дает для пользователя информацию из базы данных.
Синтаксис:
CURSOR имя_курсора IS оператор SELECT;
Курсор, являясь внутренней переменной модуля, должен быть открыт с помощью оператора:
OPEN имя_курсора;
Курсор, являясь внутренней переменной модуля, должен быть закрыт с помощью оператора:
CLOSE имя_курсора;
Выборка данных из курсора может быть выполнена в набор перемен- ных подходящих типов или в переменную типа RECORD с помощью опе- ратора:
FETCH имя_курсора INTO переменные_через_запятую; или
FETCH имя_курсора INTO имя_переменной_типа_RECORD;
При работе с курсором можно воспользоваться предопределенными атрибутами, которые представлены в табл. 4.4. Кроме того, при работе с курсором могут потребоваться атрибуты для объявления пользовательской записи и поля (табл. 4.5).
|
|
Таблица 4.4 |
Список атрибутов, используемых совместно с курсором |
||
|
|
|
Имя атрибута |
Назначение |
Образец фрагмента программы |
1 |
2 |
3 |
%FOUND |
После открытия курсора, но |
… |
|
до первого использования |
OPEN имя_курсора; |
|
оператора FETCH этот ат- |
FETCH имя_курсора INTO имя_записи; |
|
рибут содержит NULL. По- |
IF имя_курсора%FOUND THEN |
|
сле любого перемещения по |
… |
|
курсору будет TRUE, если |
ELSE |
|
последний FETCH вернул |
… |
|
запись, FALSE - последний |
|
|
FETCH не нашел запись в |
|
|
курсоре |
|
%NOTFOUND |
Атрибут, логически проти- |
|
|
воположный %FOUND |
|
45
|
|
|
|
|
Окончание табл. 4.4 |
|
1 |
|
|
2 |
3 |
|
|
%ISOPEN |
|
Атрибут возвращает TRUE, |
… |
|||
|
|
|
если курсор открыт с по- |
IF имя_курсора%ISOPEN =FALSE |
||
|
|
|
мощью оператора OPEN, |
THEN |
||
|
|
|
иначе FALSE |
|
OPEN c1; |
|
|
|
|
|
|
END IF; |
|
|
|
|
|
|
FETCH имя_курсора INTO имя_записи; |
|
|
|
|
|
|
… |
|
|
|
|
|
|
CLOSE имя_курсора; |
|
%ROWCOUNT |
|
После открытия курсора, но |
|
|
||
|
|
|
до первого использования |
|
|
|
|
|
|
оператора FETCH этот ат- |
|
|
|
|
|
|
рибут содержит 0. По мере |
|
|
|
|
|
|
перемещения по курсору на |
|
|
|
|
|
|
запись значение атрибута |
|
|
|
|
|
|
увеличивается на 1 |
|
|
|
|
|
|
|
|
Таблица 4.5 |
|
|
Атрибуты, используемые при объявлении переменных |
|||||
|
|
|
|
|
|
|
|
Название |
|
Назначение |
|
Пример объявления |
|
|
атрибута |
|
|
|
|
|
|
%ROWTYPE |
|
Позволяет |
DECLARE |
|
|
|
|
|
создать пе- |
Row1 ADMIN_BOOKS.AUTHORS%ROWTYPE; |
|
|
|
|
|
ременную |
/*объявлена переменная типа записи таблицы |
|
|
|
|
|
со всеми |
ADMIN_BOOKS.AUTHORS*/ |
|
|
|
|
|
свойсвами |
begin |
|
|
|
|
|
записи ука- |
NULL; |
|
|
|
|
|
занной таб- |
end; |
|
|
|
|
|
лицы |
|
|
|
|
%TYPE |
|
Позволяет |
DECLARE |
|
|
|
|
|
создать пе- |
COLUMN1 |
|
|
|
|
|
ременную |
ADMIN_BOOKS.AUTHORS.NAME_AUTHOR%TYPE; |
|
|
|
|
|
со всеми |
/*объявлена переменная COLUMN1 со свойствами |
|
|
|
|
|
свойствами |
столбца NAME_AUTHOR таблицы |
|
|
|
|
|
столбца |
ADMIN_BOOKS.AUTHORS*/ |
|
|
|
|
|
указанной |
begin |
|
|
|
|
|
таблицы |
NULL; |
|
|
|
|
|
|
end; |
|
|
Пример объявления курсора по таблице Авторы:
DECLARE
my_id_author NUMBER(3); -- переменная для значения Code_author my_Name_author CHAR(30); -- переменная для значения Name_author my_Birthday DATE; -- переменная для значения Birthday
CURSOR c1 IS SELECT * FROM ADMIN_BOOKS.Authors
46
WHERE Code_author > 20;
Пример объявления курсора с выбором автора и одновременным по- мещением результата в переменную:
DECLARE
my_authors ADMIN_BOOKS.Authors%ROWTYPE;
CURSOR c2 RETURN ADMIN_BOOKS.Authors%ROWTYPE IS SELECT * FROM ADMIN_BOOKS.Authors WHERE Code_author = 20;
Пример объявления курсора с использованием полей со значениями по умолчанию:
DECLARE
CURSOR c3 (low NUMBER(3) DEFAULT 0, high NUMBER(3) DEFAULT 105) IS SELECT * FROM ADMIN_BOOKS.Authors WHERE Code_author> low AND Code_author< high;
Пример работы курсора с циклом LOOP:
SET SERVEROUTPUT ON DECLARE
CURSOR c1 IS SELECT Publish, Code_publish FROM ADMIN_BOOKS.Publishing_house WHERE Code_publish<11; name1 ADMIN_BOOKS.Publishing_house.Publish %TYPE; code1 ADMIN_BOOKS.Publishing_house.Code_publish%TYPE;
BEGIN OPEN c1; LOOP
FETCH c1 INTO name1, code1;
EXIT WHEN c1%NOTFOUND OR c1%NOTFOUND IS NULL; DBMS_OUTPUT.PUT_LINE(c1%ROWCOUNT || '. ' || name1);
IF c1%ROWCOUNT = 5 THEN DBMS_OUTPUT.PUT_LINE('--- 5-я запись ---');
END IF; END LOOP; CLOSE c1; END;
Пример работы курсора с циклом WHILE:
SET SERVEROUTPUT ON DECLARE
name2 ADMIN_BOOKS.Authors.Name_author %TYPE; CURSOR authors_desc IS SELECT Name_author FROM ADMIN_BOOKS.Authors ORDER BY Name_author DESC;
BEGIN
47
OPEN authors_desc;
FETCH authors_desc INTO name2;
DBMS_OUTPUT.PUT_LINE(name2);
WHILE authors_desc%found LOOP
FETCH authors_desc INTO name2;
DBMS_OUTPUT.PUT_LINE(name2);
END LOOP;
CLOSE authors_desc;
END;
Пример работы с переменной типа Таблица с заданным списком значений
SET SERVEROUTPUT ON DECLARE
TYPE Author_list IS TABLE OF ADMIN_BOOKS.Authors.code_author%TYPE;
Authors Author_list;
Name_author_ ADMIN_BOOKS.Authors.Name_author%TYPE; Birthday_ ADMIN_BOOKS.Authors.Birthday%TYPE;
BEGIN
-- в перечне Author_list указываются реальные значения поля в таблице
Authors:= Author_list(1,2);
FOR i IN Authors.FIRST.. Authors.LAST LOOP
SELECT Name_author, Birthday INTO Name_author_, Birthday_ FROM ADMIN_BOOKS.Authors WHERE ADMIN_BOOKS.Authors.Code_Author = Authors(i);
DBMS_OUTPUT.PUT_LINE ( TO_CHAR(Authors(i)) || ': ' || Name_author_ || ', ' || Birthday_ );
END LOOP; END;
Пример работы с переменной типа Таблица с перебором записей в заголовке цикла
SET SERVEROUTPUT ON DECLARE
TYPE EmpTabTyp IS TABLE OF ADMIN_BOOKS.Authors%ROWTYPE; emp_tab EmpTabTyp;
BEGIN
for emp_tab in (SELECT * FROM ADMIN_BOOKS.Authors) loop DBMS_OUTPUT.PUT_LINE(emp_tab.code_author ||' '|| emp_tab.name_author ||' '||emp_tab.birthday);
end loop; END;
48
Пример работы с переменной типа Запись через объявление типа и через %ROWTYPE
DECLARE
Row1 ADMIN_BOOKS.AUTHORS%ROWTYPE;
TYPE TypeRec IS RECORD (minutes INTEGER, hours INTEGER);
TypeRec1 TypeRec;
/*объявлена переменная типа записи таблицы
ADMIN_BOOKS.AUTHORS*/ begin
row1.code_author:=2; row1.name_author:='Лермонтов';
row1.birthday:=TO_DATE('21-12-1980', 'dd-mm-yyyy');
insert into ADMIN_BOOKS.AUTHORS values(row1.code_author, row1.name_author, row1.birthday);
TypeRec1.minutes:=12;
TypeRec1.hours:=15;
end;
Пример передачи запроса в переменную типа Запись
SET SERVEROUTPUT ON Declare
Someone ADMIN_BOOKS.Authors%rowtype; BEGIN
FOR someone IN (SELECT * FROM ADMIN_BOOKS.Authors) LOOP
DBMS_OUTPUT.PUT_LINE('Код автора = ' || someone.code_author || ', Имя автора = ' || someone.name_author);
END LOOP; End;
Использование функций для работы со строковыми переменными
В табл. 4.6 описаны основные функции для работы со строками.
|
Таблица 4.6 |
Краткий обзор строковых функций |
|
|
|
Название функции |
Действие, выполняемое функцией |
1 |
2 |
ASCII(строка) |
Возвращает десятичное представление первого симво- |
|
ла строки согласно применяемому набору символов |
CHR(число) |
Возвращает символ, имеющий указанный в скобках |
|
код из набора символов БД. |
|
Например: Simb:= CHR(105); |
CONCAT(строка1, строка2) |
Возвращает строку 1, сцепленную со строкой 2 |
|
49 |