Cómo y cuándo usar sys_refcursor en Oracle


Respuestas:


10

Un cursor es un puntero a un conjunto de resultados para una consulta. Al devolver un sys_refcursor, permite que el cliente recupere tantas o pocas filas de la consulta como lo requiera. En aplicaciones con estado, esto podría usarse para paginar los resultados.

Un cursor puede permitir más flexibilidad que escribir una función PL / SQL que devuelva una matriz, ya que depende completamente del cliente cuántas filas buscar y cuándo detener. Dicho esto, no he encontrado muchos casos en los que esta flexibilidad adicional sea útil.

Vale la pena señalar que sys_refcursorestá tipado débilmente, por lo que puede devolver punteros a consultas que no solo tienen cláusulas diferentes o diferentes, sino también diferentes números y tipos de columnas. Alternativamente, puede usar un cursor fuertemente tipado donde las columnas en el conjunto de resultados son fijas.

Esto le permite escribir funciones que devuelven consultas diferentes, así:

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;

Sin embargo, si está utilizando sys_refcursorpara crear una función genérica de "abrir una consulta" como la anterior, ¡probablemente esté haciendo algo mal!


@ Chris ... ¿por qué su función de ejemplo es "incorrecta"?
Johnny Wu

2
@JohnnyWu será más difícil administrar la función "Consígueme cualquier cosa". ¿Cómo se prueba para asegurarse de obtener los resultados correctos en todos los casos? ¿Qué hay de la seguridad? Esto puede ser necesario si está creando un marco. Pero para la lógica comercial general, es mejor tener funciones get_empsy get_deptsfunciones separadas
Chris Saxon

1

Como ejemplo de las posibilidades: debido a que es pl / sql en la parte posterior, se puede definir un objeto para representar una fila, definir una tabla pl / sql de esos objetos,

create type T_MY_TABLE as table of t_my_object;

y terminar con

OPEN p_recordset FOR select * from table( v_my_table );

Entonces, en lugar de construir consultas directas mongo, a menudo densas y / o crípticas directas en una tabla de base de datos, uno puede crear una tabla interna y tener todo el poder de pl / sql para poblarla. Y el cliente que recopila el conjunto de resultados no es el más sabio. Y cambiar la definición de la tabla interna es más fácil desde un punto de vista de administración que cambiar una tabla de base de datos.

Además, cuando se utilizan generadores de informes como Jasper, puede extraer el SQL del informe y colocarlo en la base de datos, y simplemente llamar al procedimiento para obtener el conjunto de registros, dejando que el lado del informe se centre en el formato.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.