В прошлый раз мы пробовали работать с циклами LOOP и WHILE. Но есть один очень интересный момент, касающийся выборки данных из курсоров, а именно цикл FOR! Давайте посмотрим на классический цикл выборки LOOP:
DECLARE CURSOR get_offices IS SELECT * FROM OFFICES; -- Объявляется курсор. v_gt get_offices%ROWTYPE; -- Объявляется переменная запись, где будут хранится данные. BEGIN OPEN get_offices; -- Открывается курсор. -- Запускается цикл чтения. LOOP -- Выбираются данные. FETCH get_offices INTO v_gt; EXIT WHEN get_offices%NOTFOUND; END LOOP; -- Закрывается курсор. CLOSE get_offices; END; /
Вроде ничего не забыли. А вот, теперь посмотрите на вот такой блок:
DECLARE CURSOR get_offices IS SELECT * FROM OFFICES; BEGIN DBMS_OUTPUT.enable; FOR v_gt IN get_offices LOOP DBMS_OUTPUT.put_line('Get Data: '||TO_CHAR(v_gt.OFFICE)||' '||v_gt.CITY||' ' ||v_gt.REGION||' '||TO_CHAR(v_gt.MGR)||' '||TO_CHAR(v_gt.TARGET)||' '||TO_CHAR(v_gt.SALES)); END LOOP; END; /
После отработки в SQL*Plus получаем:
SQL> DECLARE 2 3 CURSOR get_offices IS 4 SELECT * FROM OFFICES; 5 6 BEGIN 7 8 DBMS_OUTPUT.enable; 9 10 FOR v_gt IN get_offices LOOP 11 12 DBMS_OUTPUT.put_line('Get Data: '||TO_CHAR(v_gt.OFFICE)||' '||v_gt.CITY||' ' 13 ||v_gt.REGION||' '||TO_CHAR(v_gt.MGR)||' '||TO_CHAR(v_gt.TARGET)||' '||TO_CHAR(v_gt.SALES)); 14 15 END LOOP; 16 17 END; 18 / Get Data: 22 Запиндрищинск Запад 108 300 186,042 Get Data: 11 Красный Мотоцикл Восток 106 575 692,637 Get Data: 12 Чугуевск Восток 104 800 735,044 Get Data: 13 Бубурино Восток 105 350 367,911 Get Data: 21 Котрогайка Запад 108 725 835,915 Процедура PL/SQL успешно завершена.
Действия все те же самые, но кода гораздо меньше! И вот почему. При работе с циклом FOR все становится на порядок проще, во-первых, открывать и закрывать курсор не нужно, он делает это сам не явно. Во-вотрых, объявлять переменную запись не нужно, то есть нужно, но она определяется гораздо проще, в-третьих, меньше строчек кода. Теперь по порядку, в классическом FOR:
FOR v_gt ( переменная запись, то же что и определение v_gt get_offices%ROWTYPE ) IN get_offices ( это и есть диапазон выборки сам курсор от и до как оператор .. ) LOOP начало цикла!
Вот и все, вот так FOR упрощает выборку данных из курсора! К слову хорошего стиля программирования рекомендую, если нет необходимости использовать LOOP при выборке данных из курсора, то всегда используйте FOR! :)