Freigeben über


Abrufen von Ergebnisdaten

Eine ODBC-Anwendung verfügt über drei Optionen zum Abrufen von Ergebnisdaten.

Die erste Option basiert auf SQLBindCol. Vor dem Abrufen des Resultsets verwendet die Anwendung SQLBindCol , um jede Spalte im Resultset an eine Programmvariable zu binden. Nachdem die Spalten gebunden wurden, überträgt der Treiber die Daten der aktuellen Zeile in die Variablen, die an die Resultsetspalten gebunden sind, jedes Mal, wenn die Anwendung SQLFetch oder SQLFetchScroll aufruft. Der Treiber verarbeitet Datenkonvertierungen, wenn die Resultsetspalte und die Programmvariable unterschiedliche Datentypen aufweisen. Wenn die Anwendung SQL_ATTR_ROW_ARRAY_SIZE mehr als 1 festgelegt hat, kann sie Ergebnisspalten an Arrays von Variablen binden, die alle auf jedem Aufruf von SQLFetchScroll gefüllt werden.

Die zweite Option basiert auf SQLGetData. Die Anwendung verwendet SQLBindCol nicht, um Resultsetspalten an Programmvariablen zu binden. Nach jedem Aufruf von SQLFetch ruft die Anwendung SQLGetData einmal für jede Spalte im Resultset auf. SQLGetData weist den Treiber an, Daten aus einer bestimmten Resultsetspalte an eine bestimmte Programmvariable zu übertragen, und gibt die Datentypen der Spalte und Variable an. Dadurch kann der Treiber Daten konvertieren, wenn die Ergebnisspalte und die Programmvariable unterschiedliche Datentypen aufweisen. Text-, ntext- und Bildspalten sind in der Regel zu groß, um in eine Programmvariable zu passen, können aber weiterhin mit SQLGetData abgerufen werden. Wenn die Text-, ntext- oder Bilddaten in der Ergebnisspalte größer als die Programmvariable sind, gibt SQLGetData SQL_SUCCESS_WITH_INFO und SQLSTATE 01004 zurück (Zeichenfolgendaten, rechts abgeschnitten). Aufeinander folgende Aufrufe von SQLGetData geben aufeinander folgende Blöcke der Text - oder Bilddaten zurück. Wenn das Ende der Daten erreicht ist, gibt SQLGetData SQL_SUCCESS zurück. Jeder Abruf gibt eine Reihe von Zeilen oder Rowset zurück, wenn SQL_ATTR_ROW_ARRAY_SIZE größer als 1 ist. Bevor Sie SQLGetData verwenden, müssen Sie zuerst SQLSetPos verwenden, um eine bestimmte Zeile innerhalb des Rowsets als aktuelle Zeile anzugeben.

Die dritte Option besteht darin, eine Mischung aus SQLBindCol und SQLGetData zu verwenden. Eine Anwendung kann beispielsweise die ersten zehn Spalten eines Resultsets binden und dann bei jedem Abruf SQLGetData dreimal aufrufen, um die Daten aus drei ungebundenen Spalten abzurufen. Dies wird in der Regel verwendet, wenn ein Resultset mindestens eine Text - oder Bildspalte enthält.

Abhängig von den für das Resultset festgelegten Cursoroptionen kann eine Anwendung auch die Bildlaufoptionen von SQLFetchScroll verwenden, um um das Resultset zu scrollen.

Übermäßige Verwendung von SQLBindCol zum Binden einer Resultsetspalte an eine Programmvariable ist teuer, da SQLBindCol bewirkt, dass ein ODBC-Treiber Arbeitsspeicher zuweist. Wenn Sie eine Ergebnisspalte an eine Variable binden, bleibt diese Bindung wirksam, bis Sie SQLFreeHandle aufrufen, um das Anweisungshandle freizustellen oder SQLFreeStmt aufzurufen, wobei fOption auf SQL_UNBIND festgelegt ist. Die Bindungen werden nicht automatisch rückgängig gemacht, wenn die Anweisung abgeschlossen ist.

Diese Logik ermöglicht es Ihnen, die gleiche SELECT-Anweisung mehrmals mit verschiedenen Parametern auszuführen. Da das Resultset dieselbe Struktur behält, können Sie das Resultset einmal binden, alle SELECT-Anweisungen verarbeiten und dann SQLFreeStmt mit fOption auf SQL_UNBIND nach der letzten Ausführung aufrufen. Sie sollten SQLBindCol nicht aufrufen, um die Spalten in einem Resultset zu binden, ohne zuerst SQLFreeStmt mit fOption auf SQL_UNBIND festzulegen, um vorherige Bindungen freizustellen.

Bei Verwendung von SQLBindCol können Sie entweder zeilenweise oder spaltenweise Bindung vornehmen. Zeilenweise Bindung ist etwas schneller als spaltenweise Bindung.

Sie können SQLGetData verwenden, um Daten auf Spaltenbasis anstelle von Bindungsergebnissatzspalten mithilfe von SQLBindCol abzurufen. Wenn ein Resultset nur wenige Zeilen enthält, ist die Verwendung von SQLGetData anstelle von SQLBindCol schneller; andernfalls bietet SQLBindCol die beste Leistung. Wenn Sie die Daten nicht immer in den gleichen Variablensatz einfügen, sollten Sie SQLGetData anstelle einer ständigen Neubindung verwenden. Sie können SQLGetData nur für Spalten verwenden, die sich in der Auswahlliste befinden, nachdem alle Spalten an SQLBindCol gebunden sind. Die Spalte muss auch nach allen Spalten angezeigt werden, in denen Sie SQLGetData bereits verwendet haben.

Die ODBC-Funktionen, die mit dem Verschieben von Daten in oder aus Programmvariablen umgehen, z. B. SQLGetData, SQLBindCol und SQLBindParameter, unterstützen die implizite Datentypkonvertierung. Wenn eine Anwendung z. B. eine ganze Zahl an eine Zeichenzeichenfolgenprogrammvariable bindet, konvertiert der Treiber die Daten automatisch von ganzzahl in Zeichen, bevor sie in die Programmvariable eingefügt wird.

Die Datenkonvertierung in Anwendungen sollte minimiert werden. Sofern keine Datenkonvertierung für die von der Anwendung durchgeführte Verarbeitung erforderlich ist, sollten Anwendungen Spalten und Parameter an Programmvariablen desselben Datentyps binden. Wenn die Daten jedoch von einem Typ in einen anderen konvertiert werden müssen, ist es effizienter, den Treiber für die Konvertierung zu verwenden, als dies in der Anwendung zu tun. Der SQL Server Native Client ODBC-Treiber überträgt normalerweise nur Daten direkt aus den Netzwerkpuffern an die Variablen der Anwendung. Das Anfordern des Treibers zur Datenkonvertierung zwingt den Treiber, die Daten zu puffern und CPU-Zyklen zum Konvertieren der Daten zu verwenden.

Programmvariablen sollten groß genug sein, um daten, die aus einer Spalte übertragen werden, mit Ausnahme von Text-, ntext- und Bilddaten . Wenn eine Anwendung versucht, Resultsetdaten abzurufen und sie in eine Variable zu setzen, die zu klein ist, um sie zu halten, generiert der Treiber eine Warnung. Dadurch wird der Treiber gezwungen, den Speicher für die Nachricht zuzuweisen, und der Treiber und die Anwendung müssen beide CPU-Zyklen für die Verarbeitung der Nachricht ausgeben und fehlerbehandlung durchführen. Die Anwendung sollte entweder eine Variable groß genug zuweisen, um die abgerufenen Daten zu enthalten, oder verwenden Sie die FUNKTION SUBSTRING in der Auswahlliste, um die Größe der Spalte im Resultset zu verringern.

Achten Sie bei der Verwendung von SQL_C_DEFAULT darauf, den Typ der C-Variablen anzugeben. SQL_C_DEFAULT gibt an, dass der Typ der C-Variable dem SQL-Datentyp der Spalte oder des Parameters entspricht. Wenn SQL_C_DEFAULT für eine ntext-, nchar- oder nvarchar-Spalte angegeben wird, werden Unicode-Daten an die Anwendung zurückgegeben. Dies kann verschiedene Probleme verursachen, wenn die Anwendung nicht codiert wurde, um Unicode-Daten zu verarbeiten. Die gleichen Arten von Problemen können mit dem eindeutigen Datentyp (SQL_GUID) auftreten.

Text-, ntext- und Bilddaten sind in der Regel zu groß, um in eine einzelne Programmvariable einzupassen, und wird in der Regel mit SQLGetData anstelle von SQLBindCol verarbeitet. Bei Verwendung von Servercursorn ist der SQL Server Native Client ODBC-Treiber optimiert, um die Daten für ungebundene Text-, ntext- oder Bildspalten zum Zeitpunkt des Abrufs der Zeile nicht zu übertragen. Die Text-, ntext- oder Bilddaten werden erst vom Server abgerufen, wenn die Anwendung SQLGetData für die Spalte ausgibt.

Diese Optimierung kann auf Anwendungen angewendet werden, sodass keine Text-, ntext- oder Bilddaten angezeigt werden, während ein Benutzer einen Bildlauf nach oben und unten durchführt. Nachdem der Benutzer eine Zeile ausgewählt hat, kann die Anwendung SQLGetData aufrufen, um text-, ntext- oder Bilddaten abzurufen. Dadurch werden die Übertragung von Text-, ntext- oder Bilddaten für eine der Zeilen gespeichert, die der Benutzer nicht auswählt, und die Übertragung sehr großer Datenmengen kann gespeichert werden.

Siehe auch

Verarbeiten von Ergebnissen (ODBC)