В этом примере с помощью нашего пакета открываем курсор и передаем ссылку на курсор в программу. Извлечение результатов предложений SELECT выполняется отдельными процедурами, причем для результатов с разной структурой мы вынуждены предусмотреть разные процедуры извлечения. Это – плата за минимализм и общность пакета.
Выдадим в SQL*Plus: SET SERVEROUTPUT ON
DECLARE lrc SYS_REFCURSOR;
PROCEDURE fetchandclose ( rc IN sys_refcursor) IS somename VARCHAR2 ( 20 ); BEGIN DBMS_OUTPUT.PUT_LINE ( '------------------------------' ); LOOP FETCH rc INTO somename; EXIT WHEN rc%NOTFOUND; DBMS_OUTPUT.PUT_LINE ( somename ); END LOOP; CLOSE rc; END; PROCEDURE fetch2andclose ( rc IN sys_refcursor) IS somename VARCHAR2 ( 20 ); somenumber NUMBER; BEGIN DBMS_OUTPUT.PUT_LINE ( '------------------------------' ); LOOP FETCH rc INTO somename, somenumber; EXIT WHEN rc%NOTFOUND; DBMS_OUTPUT.PUT_LINE ( RPAD ( somename, 10, ' ' ) somenumber ); END LOOP; CLOSE rc; END;
BEGIN -- Примеры:generic_ref_cursor.get_ref_cursor ( 'SELECT ename FROM emp', lrc ); fetchandclose ( lrc );
generic_ref_cursor.get_ref_cursor ( 'SELECT dname FROM dept', lrc ); fetchandclose ( lrc );
generic_ref_cursor.get_ref_cursor ( 'SELECT job, sal FROM emp', lrc ); fetch2andclose ( lrc ); END; /
(Чтобы не усложнять пример, результат на экране почти не оформляется).
Обратим внимание: программам, обрабатывающим по общей схеме однотипные курсоры, мы передаем не тексты запроса, а ссылки на уже открытый и динамически (а не статически, как в случае его определения в отдельном пакете) сформированный курсор.