Что ж, продолжаем рассматривать на примерах работу с PL/SQL - таблицами. Следующий пример показывает как работают атрибуты FIRST и LAST. Запишем такой блок:
SET SERVEROUTPUT ON -- FIRST LAST DECLARE TYPE m_SmplTable IS TABLE OF VARCHAR2(128) INDEX BY BINARY_INTEGER; MY_TBL m_SmplTable; FRST BINARY_INTEGER; LST BINARY_INTEGER; BEGIN MY_TBL(1) := 'One'; MY_TBL(3) := 'Three'; MY_TBL(-2) := 'Minus Two'; MY_TBL(0) := 'Zero'; MY_TBL(100) := 'Hundred'; DBMS_OUTPUT.enable; DBMS_OUTPUT.put_line(MY_TBL(1)); DBMS_OUTPUT.put_line(MY_TBL(3)); DBMS_OUTPUT.put_line(MY_TBL(-2)); DBMS_OUTPUT.put_line(MY_TBL(0)); DBMS_OUTPUT.put_line(MY_TBL(100)); DBMS_OUTPUT.put_line('Count table is: '||TO_CHAR(MY_TBL.COUNT)); FRST := MY_TBL.FIRST; LST := MY_TBL.LAST; DBMS_OUTPUT.put_line('Count table first: '||TO_CHAR(FRST)); DBMS_OUTPUT.put_line('Count table last: '||TO_CHAR(LST)); END; /
После запуска в SQL*Plus - получаем:
SQL> SET SERVEROUTPUT ON SQL> -- FIRST LAST SQL> DECLARE 2 3 TYPE m_SmplTable IS TABLE OF VARCHAR2(128) 4 INDEX BY BINARY_INTEGER; 5 6 MY_TBL m_SmplTable; 7 8 FRST BINARY_INTEGER; 9 LST BINARY_INTEGER; 10 11 BEGIN 12 13 MY_TBL(1) := 'One'; 14 MY_TBL(3) := 'Three'; 15 MY_TBL(-2) := 'Minus Two'; 16 MY_TBL(0) := 'Zero'; 17 MY_TBL(100) := 'Hundred'; 18 19 DBMS_OUTPUT.enable; 20 21 DBMS_OUTPUT.put_line(MY_TBL(1)); 22 DBMS_OUTPUT.put_line(MY_TBL(3)); 23 DBMS_OUTPUT.put_line(MY_TBL(-2)); 24 DBMS_OUTPUT.put_line(MY_TBL(0)); 25 DBMS_OUTPUT.put_line(MY_TBL(100)); 26 DBMS_OUTPUT.put_line('Count table is: '||TO_CHAR(MY_TBL.COUNT)); 27 28 FRST := MY_TBL.FIRST; 29 LST := MY_TBL.LAST; 30 31 DBMS_OUTPUT.put_line('Count table first: '||TO_CHAR(FRST)); 32 33 DBMS_OUTPUT.put_line('Count table last: '||TO_CHAR(LST)); 34 35 END; 36 / One Three Minus Two Zero Hundred Count table is: 5 Count table first: -2 Count table last: 100 Процедура PL/SQL успешно завершена.
Хорошо видно, что количество записей в коллекции пять, и первая запись имеет индекс -2(!), а последняя 100. Вот такая необычная ситуация, хотя здесь собственно все верно. Далее, рассмотрим на примере работу атрибутов NEXT и PRIOR. С их помощью можно перемещаться по коллекции. Рассмотрим такой блок:
SET SERVEROUTPUT ON -- NEXT PRIOR DECLARE TYPE m_SmplTable IS TABLE OF VARCHAR2(128) INDEX BY BINARY_INTEGER; MY_TBL m_SmplTable; m_Cnt BINARY_INTEGER; a BINARY_INTEGER; BEGIN FOR i IN 1..10 LOOP MY_TBL(i) := TO_CHAR(i+5); END LOOP; DBMS_OUTPUT.enable; -- FOR i IN MY_TBL.FIRST..MY_TBL.LAST LOOP -- DBMS_OUTPUT.put_line('Table is: '||TO_CHAR(MY_TBL(i))); -- END LOOP; m_Cnt := MY_TBL.FIRST; LOOP DBMS_OUTPUT.put_line('Table is: '||TO_CHAR(MY_TBL(m_Cnt))); EXIT WHEN m_Cnt = MY_TBL.LAST; m_Cnt := MY_TBL.NEXT(m_Cnt); END LOOP; m_Cnt := MY_TBL.LAST; LOOP DBMS_OUTPUT.put_line('Table is: '||TO_CHAR(MY_TBL(m_Cnt))); EXIT WHEN m_Cnt = MY_TBL.FIRST; m_Cnt := MY_TBL.PRIOR(m_Cnt); END LOOP; END; /
После запуска в SQL*Plus - получаем:
SQL> SET SERVEROUTPUT ON SQL> -- NEXT PRIOR SQL> DECLARE 2 3 TYPE m_SmplTable IS TABLE OF VARCHAR2(128) 4 INDEX BY BINARY_INTEGER; 5 6 MY_TBL m_SmplTable; 7 m_Cnt BINARY_INTEGER; 8 a BINARY_INTEGER; 9 10 BEGIN 11 12 FOR i IN 1..10 LOOP 13 MY_TBL(i) := TO_CHAR(i+5); 14 END LOOP; 15 16 DBMS_OUTPUT.enable; 17 18 -- FOR i IN MY_TBL.FIRST..MY_TBL.LAST LOOP 19 -- DBMS_OUTPUT.put_line('Table is: '||TO_CHAR(MY_TBL(i))); 20 -- END LOOP; 21 22 m_Cnt := MY_TBL.FIRST; 23 24 LOOP 25 26 DBMS_OUTPUT.put_line('Table is: '||TO_CHAR(MY_TBL(m_Cnt))); 27 EXIT WHEN m_Cnt = MY_TBL.LAST; 28 m_Cnt := MY_TBL.NEXT(m_Cnt); 29 30 END LOOP; 31 32 m_Cnt := MY_TBL.LAST; 33 34 LOOP 35 36 DBMS_OUTPUT.put_line('Table is: '||TO_CHAR(MY_TBL(m_Cnt))); 37 EXIT WHEN m_Cnt = MY_TBL.FIRST; 38 m_Cnt := MY_TBL.PRIOR(m_Cnt); 39 40 END LOOP; 41 42 END; 43 / Table is: 6 Table is: 7 Table is: 8 Table is: 9 Table is: 10 Table is: 11 Table is: 12 Table is: 13 Table is: 14 Table is: 15 Table is: 15 Table is: 14 Table is: 13 Table is: 12 Table is: 11 Table is: 10 Table is: 9 Table is: 8 Table is: 7 Table is: 6 Процедура PL/SQL успешно завершена.
Давайте детальнее рассмотрим, что здесь происходит. Первый цикл наполняет коллекцию с 1-го по 10-й элементы, затем первый цикл LOOP выводит элементы коллекции по возрастанию, а второй цикл LOOP выводит элементы коллекции по убыванию. Хорошо видно, как при этом срабатывают атрибуты NEXT, PRIOR, а так же FIRST, LAST. Кстати закомментированный второй цикл FOR делает более компактный код, можете его раcкомментировать и посмотреть, а на дом, сделать третий цикл FOR, который будет выводить как последний LOOP! Вот мы и рассмотрели на примерах работу всех атрибутов коллекций Oracle PL/SQL. Запоминайте! :)