Wie und wann sys_refcursor in oracle verwendet werden soll

9

Kann mir jemand eine kleine Erklärung geben, wie und wann jemand sys_refcursor verwenden sollte?

Alejandro Bastidas
quelle

Antworten:

9

Ein Cursor ist ein Zeiger auf eine Ergebnismenge für eine Abfrage. Durch die Rückgabe von a können sys_refcursorSie dem Client erlauben, so viele oder wenige Zeilen aus der Abfrage abzurufen, wie er benötigt. In Stateful-Anwendungen kann dies verwendet werden, um durch die Ergebnisse zu blättern.

Ein Cursor kann flexibler sein als das Schreiben einer PL / SQL-Funktion, die ein Array zurückgibt, da es vollständig dem Client überlassen bleibt, wie viele Zeilen abgerufen und wann gestoppt werden sollen. Trotzdem habe ich nicht viele Fälle gefunden, in denen diese zusätzliche Flexibilität nützlich ist.

Es ist erwähnenswert, dass das sys_refcursorschwach typisiert ist, sodass Sie Zeiger auf Abfragen zurückgeben können, die nicht nur andere als oder where-Klauseln haben, sondern auch unterschiedliche Anzahlen und Arten von Spalten. Alternativ können Sie einen stark typisierten Cursor verwenden, bei dem die Spalten in der Ergebnismenge festgelegt sind.

Auf diese Weise können Sie Funktionen schreiben, die unterschiedliche Abfragen zurückgeben, z.

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;

Wenn Sie jedoch sys_refcursoreine generische Funktion zum Öffnen einer Abfrage wie die oben genannte verwenden, machen Sie wahrscheinlich etwas falsch!

Chris Saxon
quelle
@ Chris ... warum ist deine Beispielfunktion "falsch"?
Johnny Wu
1
@JohnnyWu eine "Hol mir was" -Funktion wird schwieriger zu verwalten sein. Wie testen Sie, um sicherzustellen, dass Sie in allen Fällen die richtigen Ergebnisse erzielen? Was ist mit Sicherheit? Dies kann erforderlich sein, wenn Sie ein Framework erstellen. Aber für die allgemeine Business - Logik, ist es besser, haben separate get_empsund get_deptsFunktionen
Chris Saxon
1

Als Beispiel für die Möglichkeiten: Da es pl / sql im Hintergrund ist, kann man ein Objekt definieren, um eine Zeile darzustellen, eine pl / sql-Tabelle dieser Objekte definieren,

create type T_MY_TABLE as table of t_my_object;

und ende mit

OPEN p_recordset FOR select * from table( v_my_table );

Anstatt mongo, oft dichte und / oder kryptische direkte Abfragen in einer Datenbanktabelle zu erstellen, kann man eine interne Tabelle erstellen und die gesamte Leistung von pl / sql nutzen, um sie zu füllen. Und der Kunde, der die Ergebnismenge sammelt, ist nicht klüger. Das Ändern der Definition der internen Tabelle ist von einem Verwaltungs-POV aus einfacher als das Ändern einer Datenbanktabelle.

Auch wenn Sie Berichtsgeneratoren wie Jasper verwenden, können Sie die SQL aus dem Bericht in die Datenbank verschieben und einfach die Prozedur aufrufen, um das Recordset abzurufen, sodass sich die Berichtsseite auf die Formatierung konzentrieren kann.

J Glückseligkeit
quelle