Bagaimana dan kapan menggunakan sys_refcursor di oracle

10

Bisakah seseorang memberi saya sedikit penjelasan tentang bagaimana dan kapan seseorang harus menggunakan sys_refcursor?

Alejandro Bastidas
sumber

Jawaban:

10

Kursor adalah pointer ke hasil yang ditetapkan untuk kueri. Dengan mengembalikan sys_refcursorAnda membolehkan klien untuk mengambil sebanyak atau beberapa baris dari kueri yang diperlukan. Dalam aplikasi stateful ini dapat digunakan untuk halaman melalui hasil.

Kursor dapat memungkinkan lebih banyak fleksibilitas daripada menulis fungsi PL / SQL yang mengembalikan array karena sepenuhnya tergantung pada klien berapa banyak baris yang harus diambil dan kapan harus berhenti. Yang mengatakan, saya belum menemukan banyak kasus di mana fleksibilitas tambahan ini berguna.

Perlu dicatat bahwa sys_refcursordiketik dengan lemah, sehingga Anda dapat mengembalikan pointer ke kueri yang tidak hanya memiliki klausa berbeda dari atau di mana, tetapi juga jumlah dan jenis kolom yang berbeda. Atau Anda dapat menggunakan kursor yang sangat diketik di mana kolom dalam set hasil diperbaiki.

Ini memungkinkan Anda untuk menulis fungsi yang mengembalikan pertanyaan yang berbeda, seperti:

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;

Namun, jika Anda menggunakan sys_refcursoruntuk membuat fungsi "buka kueri" umum seperti di atas, Anda mungkin melakukan sesuatu yang salah!

Chris Saxon
sumber
@ Chris ... mengapa fungsi contoh Anda "salah?"
Johnny Wu
2
@JohnnyWu fungsi "get me anything" akan lebih sulit untuk dikelola. Bagaimana Anda menguji untuk memastikan Anda mendapatkan hasil yang benar dalam semua kasus? Bagaimana dengan keamanan? Ini mungkin diperlukan jika Anda sedang membangun kerangka kerja. Tetapi untuk logika bisnis umum, lebih baik memiliki fungsi get_empsdan terpisahget_depts
Chris Saxon
1

Sebagai contoh kemungkinan: karena itu pl / sql di belakang, seseorang dapat mendefinisikan objek untuk mewakili baris, mendefinisikan tabel pl / sql dari objek-objek itu,

create type T_MY_TABLE as table of t_my_object;

dan diakhiri dengan

OPEN p_recordset FOR select * from table( v_my_table );

Jadi, daripada membangun mongo, sering query padat dan / atau samar pada tabel database, seseorang dapat membuat tabel internal dan memiliki seluruh kekuatan pl / sql untuk mengisi itu. Dan klien yang mengumpulkan hasil tidak ada yang lebih bijaksana. Dan mengubah definisi tabel internal lebih mudah dari pov manajemen daripada mengubah tabel database.

Juga ketika menggunakan generator laporan seperti Jasper, Anda bisa mendorong SQL keluar dari laporan dan ke dalam database, dan cukup panggil prosedur untuk mendapatkan recordset, meninggalkan sisi laporan untuk fokus pada pemformatan.

J Bliss
sumber