He estado escribiendo aplicaciones web básicas durante un año (para una base de datos Oracle), y dado que las funciones son bastante simples, la mayoría de nosotros seguimos con bucles FOR regulares para obtener nuestros datos:
for i in (select * from STUDENTS) loop
htp.prn(i.student_last_name || ', ' || i.student_first_name || ' ' || i.student_dob);
end loop;
Pero, los cursores parecen ser la forma "correcta" de hacer las cosas. Puedo encontrar mucha información sobre qué son los cursores y las diferentes formas de recorrerlos, pero no puedo encontrar una razón sólida por la que usarlos en bucles FOR regulares. ¿Depende de las necesidades del procedimiento? ¿Hay ventajas inherentes que debo tener en cuenta?
FOR
es solo otra forma de usar cursores. Consulte los documentos: docs.oracle.com/cd/E11882_01/appdev.112/e10472/… De todos modos, ¿qué hace htp.prn ()?FOR
bucle es mucho más legible, creo. Tiendo a usar cursores 'reales' solo si tengo que dar un paso atrás, no solo hacia adelante. Hice esa otra pregunta porque puedo imaginar una función de tabla en lugar dehtp.prn()
.Respuestas:
Un cursor puede ser explícito o implícito, y cualquier tipo puede usarse en un bucle FOR. Realmente hay dos aspectos para su pregunta.
¿Por qué usar un cursor FOR en bucle explícito sobre un cursor FOR en bucle implícito?
¿Por qué usar un bucle con un FETCH en lugar de un bucle FOR que no tiene un FETCH explícito?
Aquí hay información útil de la documentación.
Ejemplo de cursor implícito FOR LOOP
Ejemplo de cursor explícito FOR LOOP
Cursor implícito
Cursor explícito
Cursor para declaraciones LOOP
fuente
El código que publicaste está usando un cursor. Está utilizando un bucle de cursor implícito.
Hay casos en los que el uso de un bucle de cursor explícito (es decir, declarar una variable CURSOR en la sección de declaración) produce un código más limpio o un mejor rendimiento
student_cursor
en lugar de incluir una instrucción SQL de 30 líneas que incorpora un montón de lógica. Por ejemplo, si estaba imprimiendo a todos los estudiantes que se autorizaron a graduarse y que implicaban unirse a tablas que tenían sus registros académicos, los requisitos de su programa de estudios, tablas con información sobre retenciones académicas, tablas con información sobre libros de la biblioteca vencidos, tablas con información sobre tarifas no pagadas, anulaciones administrativas, etc. Probablemente tendría sentido refactorizar el código para que esta consulta no se atasque en el medio del código que se ocupa de presentar la lista a un usuario. Eso podría implicar la creación de una vista que encapsule toda esta lógica. O podría implicar la creación de un cursor explícito que se declaró como parte del bloque PL / SQL actual o en algún bloque PL / SQL de nivel superior (es decir, un cursor declarado en un paquete) para que sea reutilizable. O puede implicar hacer algo más para encapsular y reutilizar (por ejemplo, crear una función de tabla canalizada).htp.prn
,BULK COLLECT
probablemente no le compre nada. En otros casos, sin embargo, puede resultar en mejoras sustanciales de rendimiento.fuente
Veo que muchos desarrolladores están usando cursores explícitos en lugar de cursores implícitos por viejo hábito. Esto porque en la versión 7 de Oracle, esta siempre era la forma más eficiente de hacerlo. Hoy en día generalmente hay al revés. Especialmente con el optimizador que, si es necesario, puede reescribir el cursor implícito para bucles en una recopilación masiva.
fuente
Recientemente tuve que reescribir un montón de consultas desde un bucle FOR implícito en cursores explícitos. La razón fue que las consultas obtuvieron datos de una base de datos externa a través de un enlace y esta base de datos tenía una codificación diferente a nuestra base de datos local. Al transferir datos desde el cursor implícito a un tipo de registro definido localmente, se produjeron misteriosos errores intermitentes (solo en ciertas filas específicas). Nuestro DBA nos explicó esto, no hubiéramos podido llegar al fondo de esto nosotros mismos. Parece que este es un error en Oracle que se ha informado.
Nos aconsejaron reescribir todo usando cursores explícitos y el error desapareció.
No es la razón principal por la que puede querer usar explícito sobre implícito, pero vale la pena tenerlo en cuenta.
EDITAR: Oracle 12c.
fuente