Buscar..


Sintaxis

  • Cursor cursor_name Is your_select_statement
  • Cursor cursor_name (param TYPE) es your_select_statement_using_param
  • FOR x in ( your_select_statement ) LOOP ...

Observaciones

Los cursores declarados son difíciles de usar, y usted prefiere los bucles FOR en la mayoría de los casos. Lo que es muy interesante en cursores en comparación con los bucles FOR simples, es que puede parametrizarlos.

Es mejor evitar hacer bucles con PL / SQL y cursores en lugar de usar Oracle SQL de todos modos. Sin embargo, para las personas acostumbradas al lenguaje de procedimientos, puede ser mucho más fácil de entender.

Si desea verificar si existe un registro, y luego hacer cosas diferentes dependiendo de si el registro existe o no, entonces tiene sentido usar las instrucciones MERGE en consultas SQL de ORACLE puras en lugar de usar bucles de cursor. (Tenga en cuenta que MERGE solo está disponible en las versiones de Oracle> = 9i).

Cursor parametrizado "FOR loop"

DECLARE
  CURSOR c_emp_to_be_raised(p_sal emp.sal%TYPE) IS 
    SELECT * FROM emp WHERE  sal < p_sal;
BEGIN
  FOR cRowEmp IN c_emp_to_be_raised(1000) LOOP
    dbms_Output.Put_Line(cRowEmp .eName ||' ' ||cRowEmp.sal||'... should be raised ;)');
  END LOOP;
END;
/

Cursor de bucle "FOR" implícito

BEGIN
  FOR x IN (SELECT * FROM emp WHERE sal < 100) LOOP
    dbms_Output.Put_Line(x.eName ||' '||x.sal||'... should REALLY be raised :D');
  END LOOP;
END;
/
  • La primera ventaja es que no hay ninguna declaración tediosa que hacer (piense en esta horrible cosa "CURSOR" que tenía en versiones anteriores)
  • La segunda ventaja es que primero construye su consulta de selección, luego, cuando tiene lo que desea, puede acceder de inmediato a los campos de su consulta ( x.<myfield> ) en su bucle PL / SQL
  • El bucle abre el cursor y obtiene un registro a la vez para cada bucle. Al final del bucle se cierra el cursor.
  • Los cursores implícitos son más rápidos porque el trabajo del intérprete crece a medida que el código se alarga. Cuanto menos código menos trabajo tiene que hacer el intérprete.

Trabajando con SYS_REFCURSOR

SYS_REFCURSOR se puede usar como un tipo de retorno cuando necesita manejar fácilmente una lista devuelta no desde una tabla, sino más específicamente desde una función:

función devolviendo un cursor

CREATE OR REPLACE FUNCTION list_of (required_type_in IN VARCHAR2)
   RETURN SYS_REFCURSOR
IS
   v_ SYS_REFCURSOR;
BEGIN
   CASE required_type_in
      WHEN 'CATS'
      THEN
         OPEN v_ FOR
           SELECT nickname FROM (
                select 'minou' nickname from dual
      union all select 'minâ'           from dual
      union all select 'minon'          from dual         
           );
      WHEN 'DOGS'
      THEN
         OPEN v_ FOR
              SELECT dog_call FROM (
                select 'bill'   dog_call from dual
      union all select 'nestor'          from dual
      union all select 'raoul'           from dual         
           );
   END CASE;
   -- Whit this use, you must not close the cursor.
   RETURN v_;
END list_of;
/

Y cómo usarlo:

DECLARE
   v_names   SYS_REFCURSOR;
   v_        VARCHAR2 (32767);
BEGIN
   v_names := list_of('CATS');
   LOOP
      FETCH v_names INTO v_;
      EXIT WHEN v_names%NOTFOUND;
      DBMS_OUTPUT.put_line(v_);
   END LOOP;
   -- here you close it
   CLOSE v_names;
END;
/

Manejando un CURSOR

  • Declara el cursor para escanear una lista de registros
  • Abrelo
  • Obtener el registro actual en variables (esto incrementa la posición)
  • Utilice %notfound para detectar el final de la lista
  • No olvide cerrar el cursor para limitar el consumo de recursos en el contexto actual

-

DECLARE
  CURSOR curCols IS -- select column name and type from a given table
         SELECT column_name, data_type FROM all_tab_columns where table_name='MY_TABLE';
  v_tab_column all_tab_columns.column_name%TYPE;
  v_data_type all_tab_columns.data_type%TYPE;
  v_ INTEGER := 1;
BEGIN
  OPEN curCols;
  LOOP
     FETCH curCols INTO v_tab_column, v_data_type;
     IF curCols%notfound OR v_ > 2000 THEN
       EXIT;
     END IF;
     dbms_output.put_line(v_||':Column '||v_tab_column||' is of '|| v_data_type||' Type.');
     v_:= v_ + 1;
  END LOOP;

  -- Close in any case
  IF curCols%ISOPEN THEN  
     CLOSE curCols;
  END IF;
END;
/


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow