API-Servercursor

Die APIs von OLE DB, ODBC und ADO unterstützen das Zuordnen von Cursorn zu den Resultsets von ausgeführten SQL-Anweisungen. Der MicrosoftSQL Server Native Client-OLE DB-Anbieter und der SQL Server Native Client-ODBC-Treiber implementieren diese Operationen über die Verwendung von API-Servercursorn. API-Servercursor sind Cursor, die auf dem Server implementiert und von API-Cursorfunktionen verwaltet werden. Wenn die Anwendung die API-Cursorfunktionen aufruft, wird die Cursoroperation durch den OLE DB-Anbieter oder den ODBC-Treiber an den Server übertragen.

Wird ein API-Servercursor in OLE DB, ODBC und ADO verwendet, können Sie die Funktionen oder Methoden der API folgendermaßen verwenden:

  1. Herstellen einer Verbindung.

  2. Festlegen von Attributen oder Eigenschaften, die die Merkmale des Cursors definieren, den die API automatisch jedem Resultset zuordnet.

  3. Ausführen von einer oder mehreren Transact-SQL-Anweisungen.

  4. Verwenden der API-Funktionen oder -Methoden, um die Zeilen aus den Resultsets abzurufen.

Wenn die API-Cursorattribute oder -eigenschaften auf ihre Standardwerte festgelegt sind, verwenden der SQL Server Native Client OLE DB-Anbieter und der SQL Server Native Client-ODBC-Treiber Standardresultsets. Obwohl die API in technischer Hinsicht einen Cursor anfordert, stimmen die Standardeinstellungen der Cursormerkmale mit dem Verhalten eines Standardresultsets überein. Deshalb implementieren der OLE DB-Anbieter und der ODBC-Treiber die Standardcursoroptionen mithilfe eines Standardresultsets, da es sich dabei um die effizienteste Methode handelt, Zeilen vom Server abzurufen. Wenn sie Standardresultsets verwendet, kann eine Anwendung jede Transact-SQL-Anweisung bzw. jeden -Batch ausführen, kann aber nur eine unerledigte Anweisung auf einer Verbindung haben. Die Anwendung muss also alle von einer Anweisung zurückgegebenen Resultsets verarbeiten oder abbrechen, bevor sie eine weitere Anweisung über die Verbindung ausführen kann.

Wenn die API-Cursorattribute oder -eigenschaften auf Werte festgelegt wurden, die nicht ihre Standardwerte sind, verwenden der SQL Server Native Client-OLE DB-Anbieter und der SQL Server Native Client-ODBC-Treiber API-Servercursor anstelle der Standardresultsets. Jeder Aufruf einer API-Funktion, die Zeilen abruft, generiert einen Roundtrip zum Server, um die Zeilen vom API-Servercursor abzurufen.

Einschränkungen für API-Servercursor

Eine Anwendung kann die folgenden Anweisungen beim Verwenden von API-Servercursorn nicht ausführen:

  • Transact-SQL Anweisungen, die SQL Server in Servercursorn nicht unterstützt.

  • Batches oder gespeicherte Prozeduren, die mehrere Resultsets zurückgeben.

  • SELECT-Anweisungen, die die Klauseln COMPUTE, COMPUTE BY, FOR BROWSE oder INTO enthalten.

  • Eine EXECUTE-Anweisung, die auf eine remote gespeicherte Prozedur verweist.

Implementierung von API-Servercursorn

Der SQL Server Native Client-OLE DB-Anbieter und der SQL Server Native Client-ODBC-Treiber verwenden diese speziellen gespeicherten Systemprozeduren, um dem Server Cursorvorgänge zu signalisieren:

  • sp_cursoropen definiert die SQL-Anweisung so, dass sie dem Cursor und den Cursoroptionen zugeordnet wird, und füllt anschließend den Cursor auf.

  • sp_cursorfetch ruft eine Zeile oder einen Zeilenblock vom Cursor ab.

  • sp_cursorclose schließt den Cursor und hebt seine Zuordnung auf.

  • sp_cursoroption wird verwendet, um verschiedene Cursoroptionen festzulegen.

  • sp_cursor wird verwendet, um positionierte Aktualisierungen anzufordern.

  • sp_cursorprepare kompiliert die Transact-SQL-Anweisung oder den Batch, der einem Cursor zugeordnet ist, in einen Ausführungsplan, erstellt den Cursor jedoch nicht.

  • sp_cursorexecute erstellt einen Cursor und füllt ihn auf der Grundlage des von sp_cursorprepare erstellten Ausführungsplanes auf.

  • sp_cursorunprepare verwirft den Ausführungsplan aus sp_cursorprepare.

  • sp_cursorprepexec kompiliert einen Plan für die übermittelte Transact-SQL-Anweisung oder den Batch, der einem Cursor zugeordnet ist, erstellt den Cursor und füllt ihn. sp_cursorprepexec kombiniert das Verhalten von sp_cursorprepare und sp_cursorexecute.

Diese gespeicherten Systemprozeduren werden in den Ablaufverfolgungen von SQL Server Profiler der Anwendungen von ADO, OLE DB und ODBC angezeigt, die API-Servercursor verwenden. Sie sind nur für die interne Verwendung des SQL Server Native Client-OLE DB-Anbieters und des SQL Server Native Client-ODBC-Treibers vorgesehen. Die vollständige Funktionalität dieser Prozeduren steht den Anwendungen über die Verwendung der Cursorfunktionalität der Datenbank-APIs zur Verfügung. Die Prozeduren direkt in einer Anwendung anzugeben, wird nicht unterstützt.

Wenn SQL Server eine Anweisung für eine Verbindung ausführt, kann erst dann eine andere Anweisung über diese Verbindung ausgeführt werden, wenn alle Ergebnisse der ersten Anweisung verarbeitet oder abgebrochen wurden. Diese Regel gilt auch beim Verwenden von API-Servercursorn; für die Anwendung entsteht jedoch der Eindruck, als ob SQL Server begonnen hätte, mehrere aktive Anweisungen über eine Verbindung zu unterstützen. Der Grund dafür ist, dass das vollständige Resultset im Servercursor gespeichert wird, und die einzigen Anweisungen, die an SQL Server übertragen werden, sind die Ausführungen der gespeicherten Systemprozeduren sp_cursor. SQL Server führt die gespeicherte Prozedur aus, und sobald der Client das Resultset abfragt, können auch andere Anweisungen ausgeführt werden. Der OLE DB-Anbieter und der ODBC-Treiber fragen immer alle Ergebnisse einer gespeicherten Prozedur sp_cursor ab, ehe die Anwendung die weitere Steuerung wieder übernimmt. Dies ermöglicht es Anwendungen, Abrufvorgänge mit mehreren aktiven Servercursorn zu verzahnen.

In dieser Tabelle wird dargestellt, wie eine Anwendung zwei Cursor gleichzeitig über eine Verbindung mithilfe von zwei Anweisungshandles verarbeiten kann.

Anweisungshandle 1

Anweisungshandle 2

Festlegen der Cursorattribute, sodass ein API-Servercursor verwendet wird.

 

Ausführen einer SQL-Anweisung mithilfe von SQLExecDirect. Der ODBC-Treiber ruft sp_cursoropen auf und fragt das von der Prozedur zurückgegebene Resultset ab.

 

 

Festlegen der Cursorattribute, sodass ein API-Servercursor verwendet wird.

 

Ausführen einer SQL-Anweisung mithilfe von SQLExecDirect. Der ODBC-Treiber ruft sp_cursoropen auf und fragt das von der Prozedur zurückgegebene Resultset ab.

Ausführen von SQLFetchScroll, um den ersten Zeilenblock abzurufen. Der Treiber ruft sp_cursorfetch auf und fragt dann das von der Prozedur zurückgegebene Resultset ab.

 

 

Ausführen von SQLFetchScroll, um den ersten Zeilenblock abzurufen. Der Treiber ruft sp_cursorfetch auf und fragt dann das von der Prozedur zurückgegebene Resultset ab.

Ausführen von SQLFetchScroll, um einen weiteren Zeilenblock abzurufen. Der Treiber ruft sp_cursorfetch auf und fragt dann das von der Prozedur zurückgegebene Resultset ab.

 

 

Ausführen von SQLFetchScroll, um einen weiteren Zeilenblock abzurufen. Der Treiber ruft sp_cursorfetch auf und fragt dann das von der Prozedur zurückgegebene Resultset ab.

Aufrufen von SQLFreeStmt oder SQLCloseCursor. Der Treiber ruft sp_cursorclose auf.

 

 

Aufrufen von SQLFreeStmt oder SQLCloseCursor. Der Treiber ruft sp_cursorclose auf.

Da nach dem Aufrufen einer gespeicherten Prozedur sp_cursor keine Ergebnisse für eine Verbindung offen bleiben, können Sie mehrere Transact-SQL-Anweisungen gleichzeitig über eine einzelne Verbindung ausführen, sofern diese alle mit API-Servercursorn ausgeführt werden.

Angeben von API-Servercursorn

Es folgt eine Zusammenfassung der Verwendungsweise von API-Servercursorn in den folgenden APIs:

  • OLE DB

    • Öffnen Sie ein Sitzungsobjekt, öffnen Sie ein Befehlsobjekt, und geben Sie den Befehlstext an.

    • Legen Sie Rowseteigenschaften, wie DBPROP_OTHERINSERT, DBPROP_OTHERUPDATEDELETE, DBPROP_OWNINSERT, DBPROP_OWNUDPATEDELETE fest, um das Verhalten der Cursor zu steuern.

    • Führen Sie das Befehlsobjekt aus.

    • Rufen Sie die Zeilen im Resultset mithilfe der Methoden IRowset::GetNextRows, IRowsetLocate::GetRowsAt, IRowsetLocate::GetRowsAtBookmark und IRowsetScroll::GetRowsAtRatio ab.

  • ODBC

    • Stellen Sie eine Verbindung her, und rufen Sie SQLAllocHandle auf, um Anweisungshandles zuzuordnen.

    • Rufen Sie SQLSetStmtAttr auf, um die Attribute SQL_ATTR_CURSOR_TYPE, SQL_ATTR_CONCURRENCY und SQL_ATTR_ROW_ARRAY_SIZE festzulegen. Sie können alternativ das Cursorverhalten durch Festlegen der Attribute SQL_ATTR_CURSOR_SCROLLABLE und SQL_ATTR_CURSOR_SENSITIVITY angeben.

    • Führen Sie eine Transact-SQL-Anweisung aus, entweder mit SQLExecDirect oder mit SQLPrepare und SQLExecute.

    • Rufen Sie Zeilen oder Zeilenblöcke mithilfe von SQLFetch oder SQLFetchScroll ab.

  • ADO

    • Definieren Sie ein Connection-Objekt und ein Recordset-Objekt, und führen Sie dann die Open-Methode für das Connection-Objekt aus.

    • Führen Sie die Open-Methode für das Recordset-Objekt aus, und geben Sie dabei die Parameter CursorType und/oder LockType an.

    • Rufen Sie Zeilen mithilfe der Methoden Move, MoveFirst, MoveLast, MoveNext und MovePrevious des Recordset-Objekts ab.

API-Servercursor und SET-Optionen

Wenn in SQL Server eine Abrufanweisung ausgegeben wird und es eine Änderung an einer der folgenden, den Plan beeinflussenden Optionen oder an einer der für indizierte Sichten oder berechnete Spalten benötigten Optionen gibt, verwendet der Cursor einen Snapshot der Optionswerte, die zum Zeitpunkt galten, als der Cursor geöffnet wurde. Diese Werte werden für alle nachfolgenden Abrufvorgänge verwendet, und die Änderungen im aktuellen Kontext werden ignoriert.

Den Plan beeinflussende Optionen

ARITHABORT

NUMERIC_ROUNDABORT

FORCEPLAN

QUOTED_IDENTIFIER

ANSI_NULL_DFLT_ON

ANSI_WARNINGS

ANSI_PADDING

ANSI_NULLS

CONCAT_NULL_YIELDS_NULL

DATEFIRST

DATEFORMAT

LANGUAGE

TEXTSIZE

Indizierte Sichten und berechnete Spalten

ANSI_NULLS

ANSI_PADDING

ANSI_WARNINGS

ARITHABORT (unter Kompatibilitätsgrad von 80 oder darunter) CONCAT_NULL_YIELDS_NULL

QUOTED_IDENTIFIER

NUMERIC_ROUNDABORT