J'écris des applications Web de base depuis un an (pour une base de données Oracle), et puisque les fonctions sont assez simples, la plupart d'entre nous s'en tiennent à des boucles FOR régulières pour obtenir nos données:
for i in (select * from STUDENTS) loop
htp.prn(i.student_last_name || ', ' || i.student_first_name || ' ' || i.student_dob);
end loop;
Mais les curseurs semblent être la «bonne» façon de faire les choses. Je peux trouver beaucoup d'informations sur ce que sont les curseurs et les différentes façons de les parcourir, mais je ne trouve pas de raison solide de les utiliser sur des boucles FOR régulières. Cela dépend-il des besoins de la procédure? Y a-t-il des avantages inhérents dont je devrais être conscient?
FOR
est juste une autre façon d'utiliser les curseurs. Voir les documents: docs.oracle.com/cd/E11882_01/appdev.112/e10472/… Quoi qu'il en soit, que fait htp.prn ()?FOR
boucle est beaucoup plus lisible, je pense. J'ai tendance à utiliser de «vrais» curseurs uniquement si je dois reculer, pas seulement vers l'avant. J'ai posé cette autre question parce que je peux imaginer une fonction de table au lieu dehtp.prn()
.Réponses:
Un curseur peut être explicite ou implicite, et l'un ou l'autre type peut être utilisé dans une boucle FOR. Il y a vraiment deux aspects à votre question.
Pourquoi utiliser une boucle FOR de curseur explicite sur une boucle FOR de curseur implicite?
Pourquoi utiliser une boucle avec un FETCH plutôt qu'une boucle FOR qui n'a pas de FETCH explicite?
Voici quelques informations utiles de la documentation.
Exemple de curseur implicite pour boucle
Exemple de curseur explicite pour boucle
Curseur implicite
Curseur explicite
Instructions Cursor FOR LOOP
la source
Le code que vous avez publié utilise un curseur. Il utilise une boucle de curseur implicite.
Dans certains cas, l'utilisation d'une boucle de curseur explicite (c'est-à-dire la déclaration d'une variable CURSOR dans la section déclaration) produit un code plus propre ou de meilleures performances
student_cursor
plutôt que d'inclure une instruction SQL de 30 lignes qui intègre un tas de logique. Par exemple, si vous imprimiez tous les étudiants qui ont été autorisés à obtenir leur diplôme et qui impliquaient de rejoindre des tables qui avaient leurs dossiers universitaires, les exigences de leur programme d'études, des tables contenant des informations sur les réservations académiques, des tables contenant des informations sur les livres de bibliothèque en retard, des tableaux contenant des informations sur les frais impayés, les remplacements administratifs, etc., il serait probablement judicieux de refactoriser le code afin que cette requête ne soit pas coincée au milieu du code qui concerne la présentation de la liste à un utilisateur. Cela pourrait impliquer la création d'une vue qui résumerait toute cette logique. Ou cela peut impliquer la création d'un curseur explicite qui a été déclaré comme faisant partie du bloc PL / SQL actuel ou dans un bloc PL / SQL de niveau supérieur (c'est-à-dire un curseur déclaré dans un package) afin qu'il soit réutilisable. Ou cela peut impliquer de faire autre chose pour l'encapsulation et la réutilisabilité (par exemple, la création d'une fonction de table en pipeline à la place).htp.prn
, faireBULK COLLECT
probablement ne vous rapporte rien. Dans d'autres cas, cependant, cela peut entraîner des améliorations substantielles des performances.la source
Je vois que de nombreux développeurs utilisent des curseurs explicites au lieu de curseurs implicites par habitude. En effet, dans Oracle version 7, c'était toujours la manière la plus efficace de procéder. De nos jours, il y a généralement l'inverse. Surtout avec l'optimiseur qui, si nécessaire, peut réécrire le curseur implicite pour les boucles dans une collecte en bloc.
la source
Récemment, j'ai dû réécrire un tas de requêtes à partir d'une boucle FOR implicite dans des curseurs explicites. La raison en était que les requêtes récupéraient des données d'une base de données externe via un lien et que cette base de données avait un encodage différent de notre base de données locale. Lors du transfert de données du curseur implicite vers un type d'enregistrement défini localement, de mystérieuses erreurs intermittentes se sont produites (uniquement sur certaines lignes spécifiques). Notre DBA nous a expliqué cela, nous n'aurions pas pu aller au fond des choses nous-mêmes. Il semble que ce soit un bug dans Oracle qui a été signalé.
On nous a conseillé de tout réécrire à l'aide de curseurs explicites et l'erreur a disparu.
Ce n'est pas la principale raison pour laquelle vous voudrez peut-être utiliser explicite plutôt qu'implicite, mais cela vaut la peine d'être noté.
EDIT: Oracle 12c.
la source