Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Arbeiten mit SQL-Cursorn

In SQL dienen Cursor als Zeiger, der es der Anwendungsprogrammiersprache ermöglicht, die Abfrageergebnisse zeilenweise zu verarbeiten. Dieser Artikel untersucht schnell das Konzept dahinter und zeigt, wie Cursor deklariert, geöffnet, Daten von ihnen abgerufen und dann geschlossen werden.

SQL-Cursor

Die Daten in relationalen Datenbanken werden in Form von Sets verwaltet. Daher werden Abfrageergebnisse, die von SQL SELECT-Anweisungen zurückgegeben werden, als Ergebnismengen bezeichnet. Die Ergebnismengen sind nichts anderes als Kombinationen aus einer oder mehreren Zeilen und Spalten, die aus einer oder mehreren Tabellen extrahiert wurden. Sie können durch die Ergebnissätze blättern, um die benötigten Informationen zu extrahieren. Die zurückgegebenen Datenelemente werden von Programmiersprachen wie Java oder anderen für bestimmte Anwendungszwecke verwendet. Aber hier liegt das Problem der Impedanzfehlanpassung aufgrund des Konstruktionsunterschieds zwischen Datenbankmodell und Programmiersprachenmodell.

Ein SQL-Datenbankmodell hat drei Hauptkonstrukte:

  • Spalten (oder Attribute) und ihre Datentypen
  • Zeilen (Datensätze oder Tupel)
  • Tabellen (Sammlung von Aufzeichnungen)

Daher sind primäre Diskrepanzen zwischen zwei Modellen:

  1. Die im Datenbankmodell verfügbaren Attributdatentypen sind nicht die gleichen wie die in Programmiersprachen verwendeten Variablentypen. Es gibt viele Hostsprachen und jede hat einen anderen Datentyp. Beispielsweise sind die Datentypen von C/C++ und Java unterschiedlich, ebenso wie die SQL-Datentypen. Daher ist ein Bindungsmechanismus erforderlich, um das Inkompatibilitätsproblem zu mindern.
  2. Das von SQL SELECT-Anweisungen zurückgegebene Ergebnis sind mehrere Sätze von Datensätzen, wobei jeder Datensatz eine Sammlung von Attributen ist. Host-Programmiersprachen arbeiten normalerweise mit einzelnen Datenwerten von Tupeln, die von der Abfrage zurückgegeben werden. Daher ist es wichtig, dass das Ergebnis der SQL-Abfrage der von der Programmiersprache unterstützten Datenstruktur zugeordnet wird. Der Mechanismus des Schleifens über Tupel ist notwendig, um über Tupel und ihre Attributwerte zu iterieren.

Der Cursor verhält sich wie eine Iteratorvariable, um Tupel zu durchlaufen, die von der SQL-Abfrage zurückgegeben werden, und einzelne Werte innerhalb jedes Tupels zu extrahieren, die dann geeigneten Typen von Programmvariablen zugeordnet werden können.

Der Cursor dient daher als Zeiger, der es der Programmiersprache ermöglicht, das Abfrageergebnis Datensatz für Datensatz zu verarbeiten. Ein Cursor kann alle Zeilen eines Abfrageergebnisses durchlaufen, wobei er sich jeweils auf eine Zeile konzentriert. Betrachten Sie die folgende SQL-Abfrage:

SELECT emp_no, first_name, last_name, birth_date
FROM employees
WHERE MONTH(birth_date) = MONTH(CURRENT_DATE)
AND DAY(birth_date) = DAY(CURRENT_DATE);

Das Abfrageergebnis aus der obigen Anweisung gibt Mitarbeiterdetails aller Mitarbeiter zurück, deren Geburtsdatum auf den aktuellen Tag eines bestimmten Monats fällt. Das Ergebnis kann viele Zeilen enthalten, aber die Host-Anwendungssprache kann jeweils eine Zeile verarbeiten. Als Ergebnis wird Cursor als eingebettete SQL-Anweisung innerhalb der Anwendungsprogrammiersprache deklariert. Der Cursor wird dann ähnlich wie eine Datei geöffnet und extrahiert einzelne Zeilen aus dem Abfrageergebnis. Andere Zeilen werden anschließend nacheinander extrahiert, bis der Cursor geschlossen wird.

Cursor deklarieren

Cursor werden ähnlich wie eine Variable deklariert. Es wird ein Name angegeben, es gibt Anweisungen, um den Cursor zu öffnen, das Abfrageergebnis abzurufen und schließlich den Cursor zu schließen. Beachten Sie, dass verschiedene SQL-Implementierungen die Verwendung von Cursorn auf unterschiedliche Weise unterstützen. Aber es gibt eine allgemeine Vereinbarung darüber, wie der Cursor geschrieben werden sollte.

Wir müssen SQL-Anweisungen verwenden, um die Cursor-Funktionalität vollständig zu implementieren, da das einfache Deklarieren eines Cursors nicht ausreicht, um Daten aus einer SQL-Datenbank zu extrahieren. Es gibt vier grundlegende Schritte, um einen Cursor zu deklarieren:

DEKLARE CURSOR: Die Deklaration beginnt damit, dem Cursor einen Namen zu geben und den beim Öffnen des Cursors aufzurufenden Abfrageausdruck zuzuweisen.

ÖFFNEN: Die Open-Anweisung führt den zugewiesenen Abfrageausdruck aus und stellt das Abfrageergebnis für nachfolgendes FETCH bereit.

FETCH: Ruft Datenwerte in Variablen ab, die dann an die Host-Programmiersprache oder an andere eingebettete SQL-Anweisungen übergeben werden können.

SCHLIESSEN: Der Cursor wird daran gehindert, weitere Abfrageergebnisse abzurufen.

Die Syntax lautet wie folgt:

DECLARE <cursor_name>
[SENSITIVE | INSENSITIVE | ASENSITIVE]
[SCROLL | NO SCROLL] CURSOR
[ WITH HOLD | WITHOUT HOLD]
[ WITH RETURN | WITHOUT RETURN]
FOR <sql_query_expression>
[ ORDER BY <sort_expression>]
[ FOR {READ ONLY | UPDATE [ OF <list_of_column>]}]

Der wesentliche Teil einer Cursordeklaration lautet wie folgt:

 DECLARE <cursor_name> FOR <sql_query_expression>

Der optionale Teil wie [SENSITIVE | UNEMPFINDLICH | ASENSITIVE] gibt an, ob der Cursor empfindlich auf Änderungen reagiert und diese im Abfrageergebnis widerspiegelt. SENSITIVE bedeutet, dass der Cursor von Änderungen betroffen ist, INSENSITIVE bedeutet, dass der Cursor nicht betroffen ist, und ASENSITIVE bedeutet, dass Änderungen für den Cursor sichtbar sein können oder nicht. Wenn nicht angegeben, wird die ASENSITIVE-Option angenommen.

Das optionale [SCROLLEN | NOSCROLL] definiert die Scrollfähigkeit des Cursors. Wenn nicht angegeben, wird die Option NO SCROLL angenommen.

Das optionale [ WITH HOLD | WITHOUT HOLD] definiert, ob gehalten oder automatisch geschlossen werden soll, wenn die Transaktion aufgrund des Cursors festgeschrieben wird. Wenn nicht angegeben, wird die Option WITHOUT HOLD beibehalten.

Das optionale [ WITH RETURN | WITHOUT RETURN] bestimmt, ob die Cursor-Ergebnismenge an den Aufrufer, wie z. B. eine andere SQL-Routine oder Hostsprache, zurückgegeben werden soll. Wenn nicht angegeben, bedeutet dies OHNE RÜCKGABE.

Die ORDER BY-Klausel wird verwendet, um das zurückgegebene Abfrageergebnis gemäß der angegebenen Sortiertechnik zu sortieren.

Die UPDATE-Option bezieht sich auf die Verwendung der UPDATE- oder DELETE-Anweisung in Verbindung mit den Zeilen, die von der SELECT-Anweisung des Cursors zurückgegeben werden. Eine solche Änderung ist nicht möglich, wenn wir die Option READ ONLY angeben. Wenn nicht angegeben, wird standardmäßig die UPDATE-Option angenommen.

Daher kann ein einfacher Cursor wie folgt deklariert werden:

DECLARE mycursor CURSOR
 FOR
SELECT emp_no, first_name, last_name, birth_date
  FROM employees
 WHERE MONTH(birth_date) = MONTH(CURRENT_DATE)
  AND DAY(birth_date) = DAY(CURRENT_DATE);

Cursor in MySQL

Typischerweise gibt es in MySQL zwei Arten von Cursorn:Nur-Lese- und Vorwärts-Cursor. Diese Cursor können für gespeicherte MySQL-Prozeduren verwendet werden. Diese Cursor helfen uns, die Abfrageergebnisse zeilenweise zu durchlaufen und zur weiteren Verarbeitung in Variablen abzurufen. Es ist möglich, mehr als einen Cursor zu deklarieren und sie in Schleifen zu verschachteln. Beachten Sie, dass Cursor schreibgeschützt sind, da sie verwendet werden, um temporäre Tabellen zu durchlaufen. Der Cursor führt normalerweise die Abfrage aus, wenn wir sie öffnen.

Eines der Probleme mit Cursor in MySQL besteht darin, dass sie die Leistung der Abfrage aufgrund zusätzlicher E/A-Operationen, die sie ausführen, verlangsamen könnten. Dies gilt insbesondere für wirklich große Datentypen wie BLOB und TEXT. Da Cursor mit temporären Tabellen arbeiten, werden diese Typen in In-Memory-Tabellen nicht unterstützt. Während der Arbeit mit diesen Typen muss MySQL daher temporäre Tabellen auf der Festplatte erstellen, und das erfordert viele E/A-Operationen, und das auch bei langsamen Geräten wie Festplatten. Dies ist der Hauptgrund für die langsame Leistung des Cursors.

MySQL unterstützt auch keine clientseitigen Cursor, die Client-API kann sie jedoch bei Bedarf emulieren. Aber dann ist das nicht viel anders, als das Ergebnis in einem Array in einer Programmiersprache wie Java abzurufen und es stattdessen dort zu manipulieren.

Hier ist ein Beispiel, wie man Cursor in MySQL schreibt.

CREATE PROCEDURE 'cursor_demo'()
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE id INT(11);
    DECLARE fn varchar(14);
    DECLARE ln varchar(16);
    DECLARE bdate date;
  DECLARE mycursor CURSOR FOR
  SELECT emp_no, first_name, last_name, birth_date
    FROM employees
    WHERE MONTH(birth_date)=MONTH(CURRENT_DATE)
      AND DAY(birth_date)=DAY(CURRENT_DATE);
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    OPEN mycursor;
  fetch_loop: LOOP
    FETCH mycursor INTO id, fn, ln, bdate;
  IF done THEN
      LEAVE fetch_loop;
    END IF;
    SELECT id, fn, ln, bdate;
  END LOOP;
  CLOSE mycursor;
END

Rufen Sie die gespeicherte Prozedur wie folgt auf:

mysql> CALL cursor_demo

Die Prozedur ruft die Zeilen aus einer Tabelle namens employee ab dessen Geburtsdatum mit dem aktuellen Tag und Monat in einem Cursor namens mycursor übereinstimmt und druckt sie einfach mit der SELECT-Anweisung.

Weitere Informationen finden Sie in der MySQL-Dokumentation zu Cursor.

Schlussfolgerung

Cursor sind nichts anderes als Zeiger auf die Datensätze, die von der SQL-Abfrage zurückgegeben werden. Der Zeiger zeigt typischerweise jeweils auf eine Zeile und kann in einer Schleife durchlaufen werden, um einzelne Datensätze abzurufen. SQL wird normalerweise für den direkten Aufruf verwendet, um auf Datenobjekte zuzugreifen und diese zu erstellen. Die Cursor stellen die Technik des interaktiven SQL bereit, wo sie eine Ad-hoc-Ausführung von SQL-Anweisungen ermöglichen, die durch eine Client-Anwendung ermöglicht wird. Der Mechanismus von Cursor nutzt das Datenzugriffsmodell, bei dem SQL-Anweisungen in Hostsprachen wie C, C++ oder Java usw. eingebettet sind. Dies ist nur ein kleiner Einblick in das, womit Cursor überhaupt beginnen soll. Einzelheiten zu spezifischen Normen verschiedener Implementierungen finden Sie in der entsprechenden SQL-Datenbankdokumentation.

# # #