Quelqu'un peut-il me donner une petite explication sur comment et quand quelqu'un doit-il utiliser sys_refcursor?
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!
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.