Как и когда использовать sys_refcursor в Oracle

10

Кто-нибудь может дать мне небольшое объяснение того, как и когда кто-то должен использовать sys_refcursor?

Алехандро Бастидас
источник

Ответы:

10

Курсор - это указатель на набор результатов для запроса. Возвращая a, sys_refcursorвы разрешаете клиенту извлекать столько или несколько строк из запроса, сколько требуется. В приложениях с отслеживанием состояния это можно использовать для просмотра результатов.

Курсор может обеспечить большую гибкость, чем написание функции PL / SQL, которая возвращает массив, так как клиент полностью определяет, сколько строк выбрать и когда остановить. Тем не менее, я не нашел много случаев, когда эта дополнительная гибкость полезна.

Стоит отметить, что sys_refcursorтип имеет слабую типизацию, поэтому вы можете возвращать указатели на запросы, которые имеют не только отличные от или где предложения, но и разные числа и типы столбцов. В качестве альтернативы вы можете использовать строго типизированный курсор, где столбцы в наборе результатов являются фиксированными.

Это позволяет вам писать функции, которые возвращают разные запросы, например:

create function get_data ( type varchar2 ) return sys_refcursor as
  ret_cur sys_refcursor;
begin

  if type = 'EMP' then
    open ret_cur for select * from emp;
  elsif type = 'DEPT' then
    open ret_cur for select * from dept;
  end if;

  return ret_cur;
end;

Однако, если вы используете sys_refcursorдля создания общей функции «открыть запрос», как описано выше, вы, вероятно, делаете что-то не так!

Крис Саксон
источник
@ Крис ... почему ваш пример функции "не так?"
Джонни Ву,
2
@JohnnyWu Управлять функцией «достань мне что-нибудь» будет сложнее. Как вы проверяете, чтобы убедиться, что вы получили правильные результаты во всех случаях? Как насчет безопасности? Это может быть необходимо, если вы строите фреймворк. Но для общей бизнес-логики лучше иметь отдельные функции get_empsи get_deptsфункции
Крис Саксон,
1

В качестве примера возможностей: так как это pl / sql сзади, можно определить объект для представления строки, определить таблицу pl / sql этих объектов,

create type T_MY_TABLE as table of t_my_object;

и заканчивается

OPEN p_recordset FOR select * from table( v_my_table );

Таким образом, вместо создания монго, часто плотных и / или загадочных прямых запросов к таблице базы данных, можно создать внутреннюю таблицу и иметь всю мощь pl / sql для ее заполнения. И клиент, собирающий набор результатов, не мудрее. И изменить определение внутренней таблицы проще, чем изменение таблицы базы данных.

Также при использовании генераторов отчетов, таких как Jasper, вы можете вытолкнуть SQL из отчета в базу данных и просто вызвать процедуру, чтобы получить набор записей, оставив сторону отчета сосредоточиться на форматировании.

Дж Блисс
источник