Oracle PL/SQL-Cursor: Implizit, explizit, For-Schleife mit Beispiel

⚡ Intelligente Zusammenfassung

Cursor in Oracle PL/SQL-Zeiger verweisen auf den Kontextbereich, der die von einer SQL-Anweisung zurückgegebenen Zeilen enthält. Es gibt zwei Arten: implizite Cursor, die automatisch für DML-Operationen erstellt werden, und explizite Cursor, die vom Programmierer deklariert und gesteuert werden.

  • 📍 Kontextbereich: Ein Cursor zeigt auf den Kontextbereich, der eine SQL-Anweisung und die von ihr zurückgegebene aktive Menge speichert.
  • ⚙️ Impliziter Cursor: Oracle öffnet automatisch einen impliziten Cursor für jede DML-Anweisung und jede einzelne SELECT INTO-Anweisung.
  • Explizite Cursor: Ein Programmierer deklariert, öffnet, ruft ab und schließt einen expliziten Cursor, um die volle Kontrolle zu haben.
  • 🔎 Cursorattribute: %FOUND, %NOTFOUND, %ISOPEN und %ROWCOUNT geben den Status der letzten Operation an.
  • 🔁 Cursor-FOR-Schleife: Eine FOR-Schleife öffnet, lädt und schließt einen Cursor implizit, ohne dass manuelle Schritte erforderlich sind.
  • 🤖 KI-Unterstützung: KI-Assistenten wie GitHub Copilot erkennen Cursor-Schleifen und kennzeichnen nicht geschlossene Cursor.

Oracle PL/SQL-Cursor: Implizit, Explizit und FOR-Schleife

Was ist CURSOR in PL/SQL?

Ein Cursor ist ein Zeiger auf den Kontextbereich. Oracle erstellt einen Kontextbereich für die Verarbeitung eines SQL Die Aussage und dieser Bereich enthält alle Informationen über die Aussage.

PL / SQL Der Programmierer kann den Kontextbereich mithilfe des Cursors steuern. Ein Cursor enthält die von der SQL-Anweisung zurückgegebenen Zeilen; die Menge der vom Cursor enthaltenen Zeilen wird als aktive Menge bezeichnet. Diese Cursor können auch benannt werden, sodass sie von einer anderen Stelle im Code referenziert werden können.

Es gibt zwei Arten von Cursorn:

  • Impliziter Cursor
  • Explizite Cursor

Impliziter Cursor

Wann immer DML-Operation Wird in der Datenbank eine Operation ausgeführt, wird implizit ein Cursor erstellt, der die von dieser Operation betroffenen Zeilen enthält. Diese Cursor können nicht benannt und daher nicht von anderer Stelle im Code gesteuert oder referenziert werden. Wir können nur über die Cursorattribute auf den zuletzt verwendeten Cursor zugreifen.

Explizite Cursor

Programmierer können einen benannten Kontextbereich erstellen, um ihre DML-Operationen auszuführen und so mehr Kontrolle darüber zu erhalten. Der explizite Cursor sollte im Deklarationsabschnitt der Datei definiert werden. PL/SQL-BlockEs wird für die SELECT-Anweisung erstellt, die im Code verwendet werden muss.

Nachfolgend sind die Schritte aufgeführt, die beim Arbeiten mit expliziten Cursorn erforderlich sind:

  • Deklaration des Cursors: Die Deklaration des Cursors bedeutet einfach, einen benannten Kontextbereich für die im Deklarationsteil definierte SELECT-Anweisung zu erstellen. Der Name dieses Kontextbereichs entspricht dem Cursornamen.
  • Öffnen des Cursors: Durch das Öffnen des Cursors wird PL/SQL angewiesen, den Speicher für diesen Cursor zu reservieren. Dadurch wird der Cursor bereit, die Datensätze abzurufen.
  • Daten vom Cursor abrufen: Dabei wird die SELECT-Anweisung ausgeführt und die abgerufenen Zeilen im reservierten Speicher abgelegt. Diese werden nun als aktive Mengen bezeichnet. Das Abrufen von Daten über den Cursor erfolgt auf Datensatzebene, d. h. wir können datensatzweise auf die Daten zugreifen. Jede Fetch-Anweisung ruft eine aktive Menge ab und enthält die Informationen des jeweiligen Datensatzes. Diese Anweisung entspricht einer SELECT-Anweisung, die den Datensatz abruft und ihn der Variablen in der INTO-Klausel zuweist, löst aber keine Ausnahme aus. Ausnahmen.
  • Schließen des Cursors: Sobald alle Datensätze abgerufen wurden, muss der Cursor geschlossen werden, damit der für diesen Kontextbereich reservierte Speicher freigegeben wird.

Syntax

DECLARE
CURSOR <cursor_name> IS <SELECT statement>;
<cursor_variable declaration>;
BEGIN
OPEN <cursor_name>;
FETCH <cursor_name> INTO <cursor_variable>;
.
.
CLOSE <cursor_name>;
END;

In der obigen Syntax enthält der Deklarationsteil die Deklaration des Cursors und der Cursor-Variablen, der die abgerufenen Daten zugewiesen werden. Der Cursor wird für die in der Cursor-Deklaration angegebene SELECT-Anweisung erstellt. Im Ausführungsteil wird der deklarierte Cursor geöffnet, die Daten werden abgerufen und der Cursor wird geschlossen.

Cursorattribute

Sowohl der implizite als auch der explizite Cursor verfügen über bestimmte Attribute, auf die zugegriffen werden kann. Diese Attribute liefern detailliertere Informationen zu den Cursoroperationen. Im Folgenden werden die verschiedenen Cursorattribute und ihre Verwendung erläutert.

Cursor-Attribut Beschreibung
% GEFUNDEN Gibt den booleschen Wert TRUE zurück, wenn der letzte Abrufvorgang einen Datensatz erfolgreich abgerufen hat; andernfalls wird FALSE zurückgegeben.
%NICHT GEFUNDEN Funktioniert genau entgegengesetzt zu %FOUND. Es gibt TRUE zurück, wenn der letzte Abrufvorgang keinen Datensatz finden konnte.
%IST OFFEN Gibt den booleschen Wert TRUE zurück, wenn der angegebene Cursor bereits geöffnet ist; andernfalls wird FALSE zurückgegeben.
%REIHENANZAHL Gibt einen numerischen Wert zurück, der die tatsächliche Anzahl der von der Operation betroffenen oder abgerufenen Datensätze angibt.

Beispiel für einen expliziten Cursor: In diesem Beispiel zeigen wir, wie man einen expliziten Cursor deklariert, öffnet, abruft und schließt. Wir projizieren alle Mitarbeiternamen aus der Tabelle „emp“ mithilfe eines Cursors. Außerdem verwenden wir ein Cursor-Attribut, um die Schleife so einzustellen, dass alle Datensätze aus dem Cursor abgerufen werden.

Der folgende Screenshot zeigt dieses explizite Cursor-Beispiel und seine Ausgabe. Oracle.

Beispiel für einen expliziten Cursor zum Abrufen von Mitarbeiternamen aus der Tabelle „emp“ in Oracle PL / SQL

DECLARE
CURSOR guru99_det IS SELECT emp_name FROM emp;
lv_emp_name emp.emp_name%type;
BEGIN
OPEN guru99_det;
LOOP
FETCH guru99_det INTO lv_emp_name;
IF guru99_det%NOTFOUND
THEN
EXIT;
END IF;
Dbms_output.put_line('Employee Fetched:'||lv_emp_name);
END LOOP;
Dbms_output.put_line('Total rows fetched is'||guru99_det%ROWCOUNT);
CLOSE guru99_det;
END;
/

Ausgang

Employee Fetched:BBB
Employee Fetched:XXX
Employee Fetched:YYY
Total rows fetched is 3

Code Erläuterung

  • Code Zeile 2: Deklaration des Cursors guru99_det für die Anweisung 'SELECT emp_name FROM emp'.
  • Code Zeile 3: Deklaration der Variable lv_emp_name mit der %Typ verankert an emp.emp_name.
  • Code Zeile 5: Öffne den Cursor guru99_det.
  • Code Zeile 6: Die grundlegende Schleifenanweisung wird so eingestellt, dass alle Datensätze in der Tabelle „emp“ abgerufen werden.
  • Code Zeile 7: Ruft die guru99_det-Daten ab und weist den Wert lv_emp_name zu.
  • Code Zeile 8: Mithilfe des Cursor-Attributs %NOTFOUND wird geprüft, ob alle Datensätze im Cursor abgerufen wurden. Falls ja, wird TRUE zurückgegeben und die Schleife beendet; andernfalls werden die Daten weiterhin aus dem Cursor abgerufen und ausgegeben.
  • Code Zeile 10: EXIT-Bedingung für die Schleifenanweisung.
  • Code Zeile 12: Drucken Sie den abgerufenen Mitarbeiternamen aus.
  • Code Zeile 14: Mithilfe des Cursorattributs %ROWCOUNT lässt sich die Gesamtzahl der vom Cursor abgerufenen Datensätze ermitteln.
  • Code Zeile 15: Nach Verlassen der Schleife wird der Cursor geschlossen und der reservierte Speicher freigegeben.

FOR-Schleifen-Cursor-Anweisung

Ein Cursor FOR-Schleife Die FOR-Schleife kann zur Arbeit mit Cursorn verwendet werden. Anstelle eines Bereichslimits kann der Cursorname angegeben werden, sodass die Schleife vom ersten bis zum letzten Datensatz des Cursors ausgeführt wird. Die Cursorvariable, das Öffnen, Abrufen und Schließen des Cursors erfolgen implizit durch die FOR-Schleife.

Syntax

DECLARE
CURSOR <cursor_name> IS <SELECT statement>;
BEGIN
FOR I IN <cursor_name>
LOOP
.
.
END LOOP;
END;

In der obigen Syntax enthält der Deklarationsteil die Deklaration des Cursors. Der Cursor wird für die in der Cursor-Deklaration angegebene SELECT-Anweisung erstellt. Im Ausführungsteil wird der deklarierte Cursor in der FOR-Schleife eingerichtet, und die Schleifenvariable 'I' fungiert in diesem Fall als Cursorvariable.

Oracle Cursor-for-Schleife Beispiel: In diesem Beispiel werden wir alle Mitarbeiternamen aus der Tabelle „emp“ mithilfe einer Cursor-FOR-Schleife projizieren.

DECLARE
CURSOR guru99_det IS SELECT emp_name FROM emp;
BEGIN
FOR lv_emp_name IN guru99_det
LOOP
Dbms_output.put_line('Employee Fetched:'||lv_emp_name.emp_name);
END LOOP;
END;
/

Ausgang

Employee Fetched:BBB
Employee Fetched:XXX
Employee Fetched:YYY

Code Erläuterung

  • Code Zeile 2: Deklaration des Cursors guru99_det für die Anweisung 'SELECT emp_name FROM emp'.
  • Code Zeile 4: Die FOR-Schleife für den Cursor mit der Schleifenvariablen lv_emp_name wird erstellt.
  • Code Zeile 6: Drucken des Mitarbeiternamens in jeder Iteration der Schleife.
  • Code Zeile 7: Die Schleife verlassen (END LOOP).

Hinweis: In einer Cursor-FOR-Schleife können keine Cursorattribute verwendet werden, da das Öffnen, Abrufen und Schließen des Cursors implizit durch die FOR-Schleife erfolgt.

Häufig gestellte Fragen

Ein REF-Cursor (Cursorvariable) ist ein Zeiger auf ein Abfrageergebnis-Set. Im Gegensatz zu einem statischen Cursor kann er zur Laufzeit verschiedene Abfragen öffnen und Ergebnisse zwischen PL/SQL-Blöcken oder an Clientprogramme übergeben.

Ein normaler Cursor ruft pro FETCH-Befehl eine Zeile ab, was zu vielen Kontextwechseln führt. MASSENSAMMELN Lädt viele Zeilen in einer einzigen Abfrage in eine Sammlung, wodurch der Aufwand bei großen Ergebnismengen deutlich reduziert wird.

Ja. Deklarieren Sie einen parametrisierten Cursor wie z. B. CURSOR c(dept NUMBER) IS SELECT … und übergeben Sie dann Werte bei OPEN c(10). Parameter ermöglichen die Wiederverwendung einer Cursordefinition mit unterschiedlichen Filterwerten.

FOR UPDATE sperrt die vom Cursor ausgewählten Zeilen, sodass niemand anderes sie ändern kann. WHERE CURRENT OF aktualisiert oder löscht dann genau die zuletzt abgerufene Zeile, ohne die WHERE-Bedingung zu wiederholen.

Geöffnete Cursor belegen Speicherplatz und werden auf das Limit OPEN_CURSORS angerechnet. Werden viele Cursor geöffnet gelassen, führt dies schließlich zu ORA-01000: Maximale Anzahl offener Cursor überschritten. Schließen Sie daher nach Gebrauch immer einen Cursor explizit.

Jeder FETCH-Befehl wechselt zwischen der PL/SQL- und der SQL-Engine. Tausende solcher Kontextwechsel summieren sich, daher verarbeitet eine einzelne mengenbasierte SQL-Anweisung oder ein BULK COLLECT dieselben Zeilen in der Regel wesentlich schneller.

Ja. GitHub-Copilot Erstellt explizite OPEN-, FETCH- und CLOSE-Schleifen oder Cursor-FOR-Schleifen aus einem Kommentar, fügt %NOTFOUND-Abbruchprüfungen hinzu und schlägt Attributnamen vor, obwohl Sie die Logik vorher überprüfen sollten.

KI-Assistenten erkennen zeilenweise Cursor-Schleifen, die zu mengenbasiertem SQL oder BULK COLLECT führen könnten, spüren nicht geschlossene Cursor auf und erklären das Verhalten von %attribute. Diese maschinelle Lernprüfung verbessert die Performance, bevor der Code in Produktion geht.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: