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


Ответы:


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 из отчета в базу данных и просто вызвать процедуру, чтобы получить набор записей, оставив сторону отчета сосредоточиться на форматировании.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.