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