web-dev-qa-db-fra.com

Comment et quand utiliser sys_refcursor dans Oracle

Quelqu'un peut-il me donner une petite explication sur comment et quand quelqu'un doit-il utiliser sys_refcursor?

9
Alejandro Bastidas

Un curseur est un pointeur sur un jeu de résultats pour une requête. En renvoyant un sys_refcursor vous autorisez le client à extraire autant ou quelques lignes de la requête qu'il le souhaite. Dans les applications avec état, cela peut être utilisé pour parcourir les résultats.

Un curseur peut offrir plus de flexibilité que d'écrire une fonction PL/SQL qui retourne un tableau, car c'est au client de décider du nombre de lignes à récupérer et du moment de s'arrêter. Cela dit, je n'ai pas trouvé beaucoup de cas où cette flexibilité supplémentaire est utile.

Il convient de noter que le sys_refcursor est faiblement typé, vous pouvez donc renvoyer des pointeurs vers des requêtes qui ont non seulement des clauses différentes de ou where, mais également des nombres et des types de colonnes différents. Vous pouvez également utiliser un curseur fortement typé où les colonnes du jeu de résultats sont fixes.

Cela vous permet d'écrire des fonctions qui renvoient différentes requêtes, comme ceci:

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;

Cependant, si vous utilisez sys_refcursor pour créer une fonction générique "ouvrir une requête" comme ci-dessus, vous faites probablement quelque chose de mal!

9
Chris Saxon

Comme exemple des possibilités: parce que c'est pl/sql à l'arrière, on peut définir un objet pour représenter une ligne, définir une table pl/sql de ces objets,

create type T_MY_TABLE as table of t_my_object;

et terminer avec

OPEN p_recordset FOR select * from table( v_my_table );

Ainsi, plutôt que de construire mongo, des requêtes directes souvent denses et/ou cryptiques sur une table de base de données, on peut créer une table interne et avoir toute la puissance de pl/sql pour la remplir. Et le client qui collecte l'ensemble de résultats n'est pas plus sage. Et changer la définition de la table interne est plus facile à partir d'un point de vue de gestion que de changer une table de base de données.

De plus, lorsque vous utilisez des générateurs de rapports comme Jasper, vous pouvez pousser le SQL hors du rapport et dans la base de données, et appeler simplement la procédure pour obtenir le jeu d'enregistrements, en laissant le côté du rapport se concentrer sur la mise en forme.

1
J Bliss