Zoeken…


Syntaxis

  • Cursor cursor_naam Is uw_select_statement
  • Cursor cursor_naam (param TYPE) Is uw_select_statement_using_param
  • VOOR x in ( uw_select_statement ) LUS ...

Opmerkingen

Aangegeven cursors zijn moeilijk te gebruiken en in de meeste gevallen moet u de voorkeur geven aan FOR lussen. Wat erg interessant is in cursors in vergelijking met eenvoudige FOR lussen, is dat je ze kunt parametreren.

Het is beter om lussen met PL / SQL en cursors te vermijden in plaats van Oracle SQL toch te gebruiken. Voor mensen die gewend zijn aan procedurele taal, kan het echter veel gemakkelijker te begrijpen zijn.

Als u wilt controleren of een record bestaat en vervolgens verschillende dingen doet, afhankelijk van of de record al dan niet bestaat, is het zinvol MERGE instructies te gebruiken in pure ORACLE SQL-query's in plaats van het gebruik van cursorlussen. (Merk op dat MERGE alleen beschikbaar is in Oracle-releases> = 9i).

Parameter "FOR loop" Cursor

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;
/

Impliciete cursor "FOR loop"

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;
/
  • Het eerste voordeel is dat er geen vervelende verklaring is om te doen (denk aan dit vreselijke 'CURSOR'-ding dat je in vorige versies had)
  • tweede voordeel is dat u eerst uw geselecteerde query bouwt, en wanneer u hebt wat u wilt, kunt u onmiddellijk toegang krijgen tot de velden van uw query ( x.<myfield> ) in uw PL / SQL-lus
  • De lus opent de cursor en haalt voor elke lus één record per keer op. Aan het einde van de lus is de cursor gesloten.
  • Impliciete cursors zijn sneller omdat het werk van de tolk groeit naarmate de code langer wordt. Hoe minder code, hoe minder werk de tolk hoeft te doen.

Werken met SYS_REFCURSOR

SYS_REFCURSOR kan worden gebruikt als een SYS_REFCURSOR wanneer u gemakkelijk een lijst moet verwerken die niet uit een tabel, maar meer specifiek uit een functie wordt geretourneerd:

functie retourneert een 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;
/

en hoe het te gebruiken:

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;
/

Omgaan met een CURSOR

  • Declareer de cursor om een lijst met records te scannen
  • Open het
  • Huidige record ophalen in variabelen (deze positie wordt verhoogd)
  • Gebruik %notfound om het einde van de lijst te detecteren
  • Vergeet niet de cursor te sluiten om het verbruik van hulpbronnen in de huidige context te beperken

-

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow