Jak i kiedy używać sys_refcursor w oracle

10

Czy ktoś może mi wyjaśnić, w jaki sposób i kiedy ktoś powinien użyć sys_refcursor?

Alejandro Bastidas
źródło

Odpowiedzi:

10

Kursor to wskaźnik do zestawu wyników dla zapytania. Zwracając sys_refcursor, pozwalasz klientowi pobrać tyle lub kilka wierszy z zapytania, ile wymaga. W aplikacjach stanowych można to wykorzystać do przewijania wyników.

Kursor pozwala na większą elastyczność niż pisanie funkcji PL / SQL, która zwraca tablicę, ponieważ od klienta zależy, ile wierszy należy pobrać i kiedy zatrzymać. To powiedziawszy, nie znalazłem wielu przypadków, w których ta dodatkowa elastyczność jest przydatna.

Warto zauważyć, że sys_refcursorjest on słabo wpisany, więc możesz zwracać wskaźniki do zapytań, które mają nie tylko inne klauzule lub gdzie, ale także różne liczby i typy kolumn. Alternatywnie możesz użyć mocno wpisanego kursora, w którym kolumny w zestawie wyników są stałe.

Umożliwia to pisanie funkcji zwracających różne zapytania, na przykład:

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;

Jeśli jednak używasz sys_refcursordo tworzenia ogólnej funkcji „otwórz zapytanie” takiej jak powyżej, prawdopodobnie robisz coś złego!

Chris Saxon
źródło
@Chris ... dlaczego twoja przykładowa funkcja jest „zła”?
Johnny Wu,
2
@JohnnyWu trudniej będzie zarządzać funkcją „weź mi wszystko”. Jak testujesz, aby upewnić się, że we wszystkich przypadkach masz właściwe wyniki? Co z bezpieczeństwem? Może to być konieczne, jeśli budujesz framework. Ale dla ogólnej logiki biznesowej lepiej mieć oddzielne funkcje get_empsi get_deptsfunkcje
Chris Saxon
1

Jako przykład możliwości: ponieważ z tyłu znajduje się pl / sql, można zdefiniować obiekt do reprezentowania wiersza, zdefiniować tabelę pl / sql tych obiektów,

create type T_MY_TABLE as table of t_my_object;

i zakończ z

OPEN p_recordset FOR select * from table( v_my_table );

Zamiast konstruować mongo, często gęste i / lub tajemnicze bezpośrednie zapytania w tabeli bazy danych, można stworzyć tabelę wewnętrzną i mieć całą moc pl / sql, aby ją wypełnić. A klient zbierający zestaw wyników nie jest mądrzejszy. Zmiana definicji tabeli wewnętrznej jest łatwiejsza z poziomu pov zarządzania niż zmiana tabeli bazy danych.

Również podczas korzystania z generatorów raportów, takich jak Jasper, możesz wypchnąć SQL z raportu do bazy danych i po prostu wywołać procedurę, aby uzyskać zestaw rekordów, pozostawiając stronę raportu skoncentrowaną na formatowaniu.

J Bliss
źródło