Verwenden Sie Cursor, um Zeilen aus einer Abfrage abzurufen, deren Ergebnismenge mehrere Zeilen umfasst. Ein Cursor ist ein Handle oder ein Bezeichner für die SQL-Abfrage und eine Position innerhalb der Ergebnismenge.
Eine Einführung zu Cursor finden Sie unter Mit Cursor arbeiten.
Deklarieren Sie einen Cursor für eine bestimmte SELECT-Anweisung mit der DECLARE-Anweisung.
Öffnen Sie den Cursor mit der Anweisung OPEN.
Rufen Sie mit der Anweisung FETCH einzelne Zeilen aus dem Cursor ab.
Wiederholen Sie das Abrufen von Zeilen, bis die Warnung SQLE_NOTFOUND zurückgegeben wird. Fehler- und Warnungscodes werden in der Variable SQLCODE zurückgegeben, die im SQL-Kommunikationsbereich definiert wird.
Schließen Sie den Cursor mit der CLOSE-Anweisung.
Cursor in UltraLite-Anwendungen werden immer mit der Option WITH HOLD geöffnet. Sie werden nie automatisch geschlossen. Sie müssen daher jeden Cursor explizit mit der Anweisung CLOSE schließen.
Das folgende einfache Beispiel zeigt den Gebrauch von Cursor:
void print_employees( void ) { int status; EXEC SQL BEGIN DECLARE SECTION; char name[50]; char sex; char birthdate[15]; short int ind_birthdate; EXEC SQL END DECLARE SECTION; /* 1. Declare the cursor. */ EXEC SQL DECLARE C1 CURSOR FOR SELECT emp_fname || ' ' || emp_lname, sex, birth_date FROM "DBA".employee ORDER BY emp_fname, emp_lname; /* 2. Open the cursor. */ EXEC SQL OPEN C1; /* 3. Fetch each row from the cursor. */ for( ;; ) { EXEC SQL FETCH C1 INTO :name, :sex, :birthdate:ind_birthdate; if( SQLCODE == SQLE_NOTFOUND ) { break; /* no more rows */ } else if( SQLCODE < 0 ) { break; /* the FETCH caused an error */ } if( ind_birthdate < 0 ) { strcpy( birthdate, "UNKNOWN" ); } printf( "Name: %s Sex: %c Birthdate: %s\n",name, sex, birthdate ); } /* 4. Close the cursor. */ EXEC SQL CLOSE C1; } |
Weitere Hinweise zur FETCH-Anweisung finden Sie unter FETCH-Anweisung [ESQL] [SP].
Ein Cursor wird an einer von drei Stellen positioniert:
Auf einer Zeile
Vor der ersten Zeile
Nach der letzten Zeile
Sie können die Reihenfolge der Zeilen in einem Cursor steuern, indem Sie in den SELECT-Anweisungen, die den betreffenden Cursor definieren, eine ORDER BY-Klausel einbeziehen. Wenn Sie diese Klausel nicht angeben, ist die Reihenfolge der Zeilen willkürlich.
Wenn Sie keine explizite Reihenfolge festlegen, ist nur sichergestellt, dass bei einem wiederholten Abrufen jede Zeile in der Ergebnismenge ein einziges Mal enthalten ist, bevor SQLE_NOTFOUND zurückgegeben wird.
Wenn Sie einen Cursor öffnen, befindet er sich vor der ersten Zeile. Die Anweisung FETCH verschiebt die Cursorposition automatisch nach vorne. Ein Versuch, nach der letzten Zeile eine FETCH-Anweisung auszuführen, führt zu dem Fehler SQLE_NOTFOUND, der als praktisches Signal verwendet werden kann, um die sequenzielle Verarbeitung der Zeilen abzuschließen.
Sie können den Cursor auch an eine neue absolute Position und relativ zum Anfang oder zum Ende der Abfrageergebnisse positionieren oder ihn relativ zur aktuellen Cursorposition verschieben. Mit speziellen positionierten Versionen der Anweisungen UPDATE und DELETE können Sie die Zeile an der aktuellen Cursorposition aktualisieren oder löschen. Wenn sich der Cursor vor der ersten oder nach der letzten Zeile befindet, wird ein SQLE_NOTFOUND-Fehler zurückgegeben.
Um unvorhersehbare Ergebnisse bei der expliziten Positionierung zu vermeiden, können Sie eine ORDER BY-Klausel in die SELECT-Anweisung einbeziehen, die den Cursor festlegt.
Mit der Anweisung PUT können Sie eine neue Zeile in einen Cursor einfügen.
Nach dem Aktualisieren von Daten, auf die ein offener Cursor zugreift, sollten die betreffenden Zeilen erneut abgerufen und angezeigt werden. Wird der Cursor verwendet, um eine einzelen Zeile anzuzeigen, wird mit FETCH RELATIVE 0 wieder die aktuelle Zeile gefangen. Wurde die aktuelle Zeile gelöscht, fängt der Cursor die nächste Zeile (oder es wird SQLE_NOTFOUND zurückgegeben, wenn es keine weitere Zeile mehr gibt).
Wenn eine temporäre Tabelle für den Cursor verwendet wird, erscheinen die in die zugrunde liegenden Tabellen eingefügten Zeilen nicht, bis der Cursor geschlossen und erneut geöffnet wird. Es ist für die meisten Programmierer schwierig zu beurteilen, ob eine temporäre Tabelle von einer SELECT-Anweisung betroffen ist, ohne den vom SQL-Präprozessor generierten Code zu untersuchen bzw. ohne genaue Kenntnis der Bedingungen, unter denen temporäre Tabellen verwendet werden. Sie können temporäre Tabellen gewöhnlich vermeiden, indem Sie in der ORDER BY-Klausel einen Index für die Spalten haben.
Weitere Hinweise zu temporären Tabellen finden Sie unter Arbeitstabellen in der Abfrageverarbeitung verwenden ("Alle Zeilen" als Optimierungsziel verwenden).
Einfügungen, Aktualisierungen und Löschungen in nicht-temporären Tabellen können sich auf die Cursorposition auswirken. Da UltraLite Cursor-Zeilen jeweils einzeln materialisiert, (wenn keine temporäre Tabellen verwendet werden), können sich die Daten aus einer soeben eingefügten Zeile (oder das Fehlen von Daten aus einer soeben gelöschten Zeile) in nachfolgenden FETCH-Vorgängen auswirken. In einem einfachen Fall, in dem (Teile von) Zeilen aus einer einzelnen Tabelle ausgewählt werden, erscheint eine eingefügte oder geänderte Zeile in der Ergebnismenge des Cursors, wenn sie die Auswahlkriterien der SELECT-Anweisung erfüllt. Ebenso ist eine soeben gelöschte Zeile, die zuvor zur Ergebnismenge beigetragen hat, nicht länger enthalten.
Kommentieren Sie diese Seite in DocCommentXchange. Senden Sie uns Feedback über diese Seite via E-Mail. |
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |