Раньше мы с вами рассматривали оператор SELECT, который получал все данные из таблиц. Но как известно, чаще вы будете использовать условие WHERE в курсорном операторе SELECT. И в дальнейшем вам будет необходимо определять условия выборки. Как это сделать наиболее правильно, самый простой способ вот так:
-- Пишем курсор с условием CURSOR get_sls IS SELECT * FROM SALESREPS WHERE AGE = 37;
Замечательно, а если нужно другое значение отличное от 37? Что тогда? Напрашивается вывод о том, что в этом случае необходим курсор с параметрами или "параметризованный курсор"! Он определяется вот так:
CURSOR get_sls(INAGE NUMBER) IS SELECT * FROM SALESREPS WHERE AGE = INAGE;
Но еще более правильно, будет сделать вот так:
CURSOR get_sls(INAGE SALESREPS.AGE%TYPE) IS SELECT * FROM SALESREPS WHERE AGE = INAGE;
Применив оператор TYPE мы сделали код более мобильным, так как если тип поля изменится, то не нужно будет лопатить весь код в поисках ошибки! Это так же считается наиболее правильным стилем программирования! :) И теперь при открытии такого курсора, его оператор OPEN будет принимать передаваемый параметр вот так:
OPEN get_sls(37);
Подытожим наши заключения следующим блоком:
SET SERVEROUTPUT ON
DECLARE
CURSOR get_sls(INAGE SALESREPS.AGE%TYPE) IS
SELECT * FROM SALESREPS
WHERE AGE = INAGE;
in_sls get_sls%ROWTYPE;
BEGIN
DBMS_OUTPUT.enable;
OPEN get_sls(37);
FETCH get_sls INTO in_sls;
LOOP
DBMS_OUTPUT.put_line('Record is: '||in_sls.NAME||' '||in_sls.TITLE||' '||in_sls.HIRE_DATE);
FETCH get_sls INTO in_sls;
EXIT WHEN get_sls%NOTFOUND;
END LOOP;
CLOSE get_sls;
END;
/
После запуска получаем:
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
2
3 CURSOR get_sls(INAGE SALESREPS.AGE%TYPE) IS
4 SELECT * FROM SALESREPS
5 WHERE AGE = INAGE;
6
7 in_sls get_sls%ROWTYPE;
8
9 BEGIN
10
11 DBMS_OUTPUT.enable;
12
13 OPEN get_sls(37);
14
15 FETCH get_sls INTO in_sls;
16
17 LOOP
18
19 DBMS_OUTPUT.put_line('Record is: '||in_sls.NAME||' '||in_sls.TITLE||' '||in_sls.HIRE_DATE);
20
21 FETCH get_sls INTO in_sls;
22 EXIT WHEN get_sls%NOTFOUND;
23
24 END LOOP;
25
26 CLOSE get_sls;
27
28 END;
29 /
Record is: Вася Пупкин Рапорт продажа 12.02.88
Record is: Максим Галкин Продано все 12.10.89
Процедура PL/SQL успешно завершена.
Вот так отработал наш с вами первый параметризованный курсор, надеюсь, все понятно, если нет - спрашивайте! Для закрепления, давайте запишем тот же курсор, с циклом FOR:
SET SERVEROUTPUT ON
DECLARE
CURSOR get_sls(INAGE SALESREPS.AGE%TYPE) IS
SELECT * FROM SALESREPS
WHERE AGE = INAGE;
BEGIN
DBMS_OUTPUT.enable;
FOR in_sls IN get_sls(37) LOOP
DBMS_OUTPUT.put_line('Record is: '||in_sls.NAME||' '||in_sls.TITLE||' '||in_sls.HIRE_DATE);
END LOOP;
END;
/
Получаем:
SQL> DECLARE
2
3 CURSOR get_sls(INAGE SALESREPS.AGE%TYPE) IS
4 SELECT * FROM SALESREPS
5 WHERE AGE = INAGE;
6
7 BEGIN
8
9 DBMS_OUTPUT.enable;
10
11 FOR in_sls IN get_sls(37) LOOP
12
13 DBMS_OUTPUT.put_line('Record is: '||in_sls.NAME||' '||in_sls.TITLE||' '||in_sls.HIRE_DATE);
14
15 END LOOP;
16
17 END;
18 /
Record is: Вася Пупкин Рапорт продажа 12.02.88
Record is: Максим Галкин Продано все 12.10.89
Процедура PL/SQL успешно завершена.
Параметров у курсора может быть несколько, например вот так:
SET SERVEROUTPUT ON
DECLARE
CURSOR get_sls(INMG SALESREPS.MANAGER%TYPE, INSL SALESREPS.SALES%TYPE) IS
SELECT * FROM SALESREPS
WHERE MANAGER = INMG AND SALES > INSL;
BEGIN
DBMS_OUTPUT.enable;
FOR in_sls IN get_sls(104, 300) LOOP
DBMS_OUTPUT.put_line('Record is: '||in_sls.NAME||' '||in_sls.TITLE||' '||TO_CHAR(in_sls.HIRE_DATE,'DD-MM-YYYY')||
' '||TO_CHAR(in_sls.SALES));
END LOOP;
END;
/
Получаем после запуска:
SQL> DECLARE
2
3 CURSOR get_sls(INMG SALESREPS.MANAGER%TYPE, INSL SALESREPS.SALES%TYPE) IS
4 SELECT * FROM SALESREPS
5 WHERE MANAGER = INMG AND SALES > INSL;
6
7 BEGIN
8
9 DBMS_OUTPUT.enable;
10
11 FOR in_sls IN get_sls(104, 300) LOOP
12
13 DBMS_OUTPUT.put_line('Record is: '||in_sls.NAME||' '||in_sls.TITLE||' '||TO_CHAR(in_sls.HIRE_DATE,'DD-MM-YYYY')||
14 ' '||TO_CHAR(in_sls.SALES));
15
16 END LOOP;
17
18 END;
19 /
Record is: Вася Пупкин Рапорт продажа 12-02-1988 367,911
Record is: Игорь Николаев Рапорт продажа 20-10-1986 305,673
Процедура PL/SQL успешно завершена.
Что собственно и требовалось доказать. Вот так работают курсоры с параметрами и без таковых. Надеюсь, теперь вы научились писать курсоры, и выбирать из них данные! :)