Abrufen von Ergebnisdaten
Gilt für: SQL Server Azure SQL-Datenbank Azure SQL verwaltete Instanz Azure Synapse Analytics Analytics Platform System (PDW)
Eine ODBC-Anwendung bietet 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 führt Datenkonvertierungen durch, wenn die Resultsetspalte und die Programmvariable verschiedene 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 ausgefü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. Dies ermöglicht es dem Treiber, Daten zu konvertieren, wenn die Datentypen der Ergebnisspalte und der Programmvariablen nicht übereinstimmen. 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 der Text, der nText oder die 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 einen Satz von Zeilen oder ein 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 Ihnen das effektive Ausführen derselben SELECT-Anweisung mehrere Male mit verschiedenen Parametern. 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. Zeilenbezogene Bindungen sind etwas schneller als spaltenbezogene Bindungen.
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 beispielsweise eine Anwendung eine Spalte mit ganzen Zahlen an eine Zeichenfolgen-Programmvariable bindet, konvertiert der Treiber automatisch die Daten aus einer ganzen Zahl in ein Zeichen, bevor sie in der Programmvariablen abgelegt werden.
Datenkonvertierungen in Anwendungen sollten reduziert werden. Nur wenn eine 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 von einem Typ in einen anderen konvertiert werden müssen, ist es effektiver, wenn der Treiber die Konvertierung durchführt, anstatt dies in der Anwendung durchzuführen. Der SQL Server Native Client ODBC-Treiber überträgt normalerweise nur Daten direkt aus den Netzwerkpuffern an die Variablen der Anwendung. Wenn Sie die Datenkonvertierung durch den Treiber anfordern, zwingt dies den Treiber, die Daten zu puffern und CPU-Zyklen für das 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 in einer Variablen abzulegen, die für die Aufnahme dieser Daten zu klein ist, generiert der Treiber eine Warnung. Dies zwingt den Treiber, Speicher für die Meldung zu belegen, und sowohl der Treiber als auch die Anwendung müssen CPU-Zyklen für die Verarbeitung der Meldung und die Durchführung der Fehlerbehandlung aufwenden. Die Anwendung sollte entweder eine Variable zuordnen, die groß genug ist, die abgerufenen Daten aufzunehmen, oder die SUBSTRING-Funktion in der Auswahlliste verwenden, um die Größe der Spalte im Resultset zu reduzieren.
Beim Verwenden von SQL_C_DEFAULT zur Angabe des Typs der C-Variablen müssen Sie mit Bedacht vorgehen. SQL_C_DEFAULT gibt an, dass der Typ der C-Variablen mit dem SQL-Datentyp der Spalte oder des Parameters übereinstimmt. 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 behandeln. Dieselben Arten von Problemen können mit dem eindeutigen Identifikationsdatentyp (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.