Suche…


Syntax

  • Cursorcursorname Ist Ihre_Auswahl_Ausrichtung
  • Cursorcursorname (param TYPE) ist Ihr_select_statement_using_param
  • FOR x in ( your_select_statement ) LOOP ...

Bemerkungen

Deklarierte Cursor sind schwer zu verwenden, und Sie sollten in den meisten Fällen FOR Schleifen bevorzugen. Im Vergleich zu einfachen FOR Schleifen ist es bei Cursor sehr interessant, dass Sie sie parametrieren können.

Es ist besser, Schleifen mit PL / SQL und Cursors zu vermeiden, anstatt ohnehin Oracle SQL zu verwenden. Für Menschen, die an prozedurale Sprache gewöhnt sind, kann dies jedoch viel einfacher zu verstehen sein.

Wenn Sie prüfen möchten, ob ein Datensatz vorhanden ist, und je nachdem, ob der Datensatz vorhanden ist oder nicht, dann verschiedene MERGE ausführen, ist es sinnvoll, MERGE Anweisungen in reinen ORACLE SQL-Abfragen anstelle von Cursor-Schleifen zu verwenden. (Bitte beachten Sie, dass MERGE nur in Oracle-Versionen> = 9i verfügbar ist).

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

Impliziter "FOR-Loop" -Cursor

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;
/
  • Der erste Vorteil ist, dass es keine langwierige Erklärung gibt (denken Sie an diese schreckliche "CURSOR" -Erinnerung, die Sie in früheren Versionen hatten).
  • Der zweite Vorteil besteht darin, dass Sie zunächst Ihre Auswahlabfrage erstellen. Wenn Sie dann das haben, was Sie möchten, können Sie sofort auf die Felder Ihrer Abfrage ( x.<myfield> ) in Ihrer PL / SQL-Schleife x.<myfield>
  • Die Schleife öffnet den Cursor und ruft für jede Schleife jeweils einen Datensatz ab. Am Ende der Schleife wird der Cursor geschlossen.
  • Implizite Cursor sind schneller, da die Arbeit des Interpreters zunimmt, je länger der Code wird. Je weniger Code, desto weniger Arbeit muss der Dolmetscher leisten.

Mit SYS_REFCURSOR arbeiten

SYS_REFCURSOR kann als Rückgabetyp verwendet werden, wenn Sie eine Liste, die nicht aus einer Tabelle, sondern insbesondere aus einer Funktion zurückgegeben wird, problemlos bearbeiten können:

Funktion, die einen Cursor zurückgibt

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

und wie man es benutzt:

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

Umgang mit einem CURSOR

  • Deklarieren Sie den Cursor, um eine Liste der Datensätze zu scannen
  • Öffne es
  • Aktuellen Datensatz in Variablen abrufen (Position wird erhöht)
  • Verwenden Sie %notfound , um das Ende der Liste zu ermitteln
  • Vergessen Sie nicht, den Cursor zu schließen, um den Ressourcenverbrauch im aktuellen Kontext zu begrenzen

-

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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow