Teilen über


SQLGetData-Funktion

Konformität
Eingeführte Version: ODBC 1.0-Standards Compliance: ISO 92

Zusammenfassung
SQLGetData ruft Daten für eine einzelne Spalte im Resultset oder für einen einzelnen Parameter ab, nachdem SQLParamData SQL_PARAM_DATA_AVAILABLE zurückgibt. Sie kann mehrmals aufgerufen werden, um Daten mit variabler Länge in Teilen abzurufen.

Syntax

  
SQLRETURN SQLGetData(  
      SQLHSTMT       StatementHandle,  
      SQLUSMALLINT   Col_or_Param_Num,  
      SQLSMALLINT    TargetType,  
      SQLPOINTER     TargetValuePtr,  
      SQLLEN         BufferLength,  
      SQLLEN *       StrLen_or_IndPtr);  

Argumente

StatementHandle
[Eingabe] Anweisungshandle.

Col_or_Param_Num
[Eingabe] Zum Abrufen von Spaltendaten ist dies die Nummer der Spalte, für die Daten zurückgegeben werden sollen. Resultsetspalten werden ab 1 in erhöhter Spaltenreihenfolge nummeriert. Die Lesezeichenspalte ist die Spaltennummer 0; dies kann nur angegeben werden, wenn Lesezeichen aktiviert sind.

Zum Abrufen von Parameterdaten ist dies die Ordnungszahl des Parameters, der bei 1 beginnt.

TargetType
[Eingabe] Der Typbezeichner des C-Datentyps des *TargetValuePtr-Puffers . Eine Liste der gültigen C-Datentypen und Typbezeichner finden Sie im Abschnitt C-Datentypen in Anhang D: Datentypen.

Wenn TargetType SQL_ARD_TYPE ist, verwendet der Treiber den Typbezeichner, der im Feld SQL_DESC_CONCISE_TYPE der ARD angegeben ist. Wenn TargetType SQL_APD_TYPE ist, verwendet SQLGetData denselben C-Datentyp, der in SQLBindParameter angegeben wurde. Andernfalls überschreibt der in SQLGetData angegebene C-Datentyp den in SQLBindParameter angegebenen C-Datentyp. Wenn es SQL_C_DEFAULT ist, wählt der Treiber den Standarddatentyp C basierend auf dem SQL-Datentyp der Quelle aus.

Sie können auch einen erweiterten C-Datentyp angeben. Weitere Informationen finden Sie unter C-Datentypen in ODBC.

TargetValuePtr
[Ausgabe] Zeiger auf den Puffer, in dem die Daten zurückgegeben werden sollen.

TargetValuePtr darf nicht NULL sein.

BufferLength
[Eingabe] Länge des *TargetValuePtr-Puffers in Bytes.

Der Treiber verwendet BufferLength , um zu vermeiden, dass beim Zurückgeben von Daten mit variabler Länge, z. B. Zeichen- oder Binärdaten, über das Ende des *TargetValuePtr-Puffers hinaus geschrieben wird. Beachten Sie, dass der Treiber das NULL-Terminierungszeichen zählt, wenn Zeichendaten an *TargetValuePtr zurückgegeben werden. *TargetValuePtr muss daher Leerzeichen für das NULL-Terminierungszeichen enthalten, andernfalls schneidet der Treiber die Daten ab.

Wenn der Treiber Daten mit fester Länge zurückgibt, z. B. eine ganze Zahl oder eine Datumsstruktur, ignoriert der Treiber BufferLength und geht davon aus, dass der Puffer groß genug ist, um die Daten zu speichern. Daher ist es wichtig, dass die Anwendung einen ausreichend großen Puffer für Daten mit fester Länge zuweist, da sonst der Treiber über das Ende des Puffers hinaus schreibt.

SQLGetData gibt SQLSTATE HY090 (Ungültige Zeichenfolgen- oder Pufferlänge) zurück, wenn BufferLength kleiner als 0 ist, aber nicht, wenn BufferLength 0 ist.

StrLen_or_IndPtr
[Ausgabe] Zeiger auf den Puffer, in dem die Länge oder der Indikatorwert zurückgegeben werden soll. Wenn dies ein NULL-Zeiger ist, wird kein Längen- oder Indikatorwert zurückgegeben. Dadurch wird ein Fehler zurückgegeben, wenn die abgerufenen Daten NULL sind.

SQLGetData kann die folgenden Werte im Längen-/Indikatorpuffer zurückgeben:

  • Die Länge der zurückzugebenden Daten

  • SQL_NO_TOTAL

  • SQL_NULL_DATA

Weitere Informationen finden Sie unter Verwenden von Längen-/Indikatorwerten und "Kommentaren" in diesem Thema.

Gibt zurück

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_STILL_EXECUTING, SQL_ERROR oder SQL_INVALID_HANDLE.

Diagnose

Wenn SQLGetData entweder SQL_ERROR oder SQL_SUCCESS_WITH_INFO zurückgibt, kann ein zugeordneter SQLSTATE-Wert abgerufen werden, indem SQLGetDiagRec mit einem HandleType von SQL_HANDLE_STMT und einem Handle von StatementHandle aufgerufen wird. In der folgenden Tabelle sind die SQLSTATE-Werte aufgeführt, die häufig von SQLGetData zurückgegeben werden, und die einzelnen Werte werden im Kontext dieser Funktion erläutert. die Notation "(DM)" steht vor den Beschreibungen von SQLSTATEs, die vom Treiber-Manager zurückgegeben werden. Der Rückgabecode, der jedem SQLSTATE-Wert zugeordnet ist, ist SQL_ERROR, sofern nicht anders angegeben.

SQLSTATE Fehler BESCHREIBUNG
01000 Allgemeine Warnung Treiberspezifische Informationsmeldung. (Funktion gibt SQL_SUCCESS_WITH_INFO zurück.)
01004 Zeichenfolgendaten, rechts abgeschnitten Nicht alle Daten für die angegebene Spalte Col_or_Param_Num konnten in einem einzigen Aufruf der Funktion abgerufen werden. SQL_NO_TOTAL oder die Länge der Daten, die vor dem aktuellen Aufruf von SQLGetData in der angegebenen Spalte verbleiben, wird in *StrLen_or_IndPtr zurückgegeben. (Funktion gibt SQL_SUCCESS_WITH_INFO zurück.)

Weitere Informationen zur Verwendung mehrerer Aufrufe von SQLGetData für eine einzelne Spalte finden Sie unter Kommentare.
01S07 Bruchkürzung Die für eine oder mehrere Spalten zurückgegebenen Daten wurden abgeschnitten. Bei numerischen Datentypen wurde der Bruchteil der Zahl abgeschnitten. Für die Datentypen time, timestamp und interval, die eine Zeitkomponente enthalten, wurde der Bruchteil der Zeit abgeschnitten.

(Funktion gibt SQL_SUCCESS_WITH_INFO zurück.)
07006 Verletzung des eingeschränkten Datentyp-Attributs Der Datenwert einer Spalte im Resultset kann nicht in den vom Argument TargetType angegebenen C-Datentyp konvertiert werden.
07009 Ungültiger Deskriptorindex Der für das Argument Col_or_Param_Num angegebene Wert war 0, und das SQL_ATTR_USE_BOOKMARKS-Anweisungsattribut wurde auf SQL_UB_OFF festgelegt.

Der für das Argument Col_or_Param_Num angegebene Wert war größer als die Anzahl der Spalten im Resultset.

Der Col_or_Param_Num Wert war nicht gleich der Ordnungszahl des verfügbaren Parameters.

(DM) Die angegebene Spalte wurde gebunden. Diese Beschreibung gilt nicht für Treiber, die die SQL_GD_BOUND Bitmaske für die Option SQL_GETDATA_EXTENSIONS in SQLGetInfo zurückgeben.

(DM) Die Anzahl der angegebenen Spalte war kleiner oder gleich der Anzahl der höchsten gebundenen Spalte. Diese Beschreibung gilt nicht für Treiber, die die SQL_GD_ANY_COLUMN Bitmaske für die Option SQL_GETDATA_EXTENSIONS in SQLGetInfo zurückgeben.

(DM) Die Anwendung hat bereits SQLGetData für die aktuelle Zeile aufgerufen. Die Nummer der spalte, die im aktuellen Aufruf angegeben wurde, war kleiner als die Nummer der Spalte, die im vorherigen Aufruf angegeben wurde. und der Treiber gibt die SQL_GD_ANY_ORDER Bitmaske für die option SQL_GETDATA_EXTENSIONS in SQLGetInfo nicht zurück.

(DM) Das Argument TargetType wurde SQL_ARD_TYPE, und der Col_or_Param_Num-Deskriptordatensatz in der ARD hat die Konsistenzprüfung nicht bestanden.

(DM) Das Argument TargetType wurde SQL_ARD_TYPE, und der Wert im SQL_DESC_COUNT-Feld der ARD war kleiner als das argument Col_or_Param_Num .
08S01 Kommunikationslinkfehler Die Kommunikationsverbindung zwischen dem Treiber und der Datenquelle, mit der der Treiber verbunden wurde, ist fehlgeschlagen, bevor die Verarbeitung der Funktion abgeschlossen wurde.
22002 Indikatorvariable erforderlich, aber nicht angegeben StrLen_or_IndPtr war ein NULL-Zeiger, und NULL-Daten wurden abgerufen.
22003 Numerischer Wert außerhalb des Bereichs Die Rückgabe des numerischen Werts (als Numerische oder Zeichenfolge) für die Spalte hätte dazu geführt, dass der gesamte Teil (im Gegensatz zu Bruchzahlen) der Zahl abgeschnitten wurde.

Weitere Informationen finden Sie im Anhang D: Datentypen.
22007 Ungültiges datetime-Format Die Zeichenspalte im Resultset wurde an eine C-Datums-, Uhrzeit- oder Zeitstempelstruktur gebunden, und der Wert in der Spalte war ein ungültiger Datums-, Uhrzeit- oder Zeitstempel. Weitere Informationen finden Sie im Anhang D: Datentypen.
22012 Division durch 0 Ein Wert aus einem arithmetischen Ausdruck, der zu einer Division durch 0 (null) geführt hat, wurde zurückgegeben.
22015 Intervallfeldüberlauf Das Zuweisen eines genauen numerischen oder Intervall-SQL-Typs zu einem Intervall-C-Typ führte zu einem Verlust signifikanter Ziffern im führenden Feld.

Beim Zurückgeben von Daten an einen Intervall-C-Typ gab es keine Darstellung des Werts des SQL-Typs im Intervall C-Typ.
22018 Ungültiger Zeichenwert für die Umwandlungsspezifikation Eine Zeichenspalte im Resultset wurde an einen Zeichen C-Puffer zurückgegeben, und die Spalte enthielt ein Zeichen, für das im Zeichensatz des Puffers keine Darstellung vorhanden war.

Der C-Typ war ein genauer oder ungefährer numerischer Datentyp, ein datetime- oder ein Intervalldatentyp. Der SQL-Typ der Spalte war ein Zeichendatentyp; und der Wert in der Spalte war kein gültiges Literal des gebundenen C-Typs.
24.000 Ungültiger Cursorstatus (DM) Die Funktion wurde aufgerufen, ohne zuerst SQLFetch oder SQLFetchScroll aufzurufen, um den Cursor in der erforderlichen Datenzeile zu positionieren.

(DM) Das StatementHandle befand sich in einem ausgeführten Zustand, aber es wurde kein Resultset dem StatementHandle zugeordnet.

Im StatementHandle war ein Cursor geöffnet, und SQLFetch oder SQLFetchScroll wurde aufgerufen, aber der Cursor wurde vor dem Anfang des Resultsets oder nach dem Ende des Resultsets positioniert.
HY000 Allgemeiner Fehler Es ist ein Fehler aufgetreten, für den kein spezifischer SQLSTATE-Wert vorhanden war und für den keine implementierungsspezifische SQLSTATE definiert wurde. Die von SQLGetDiagRec im MessageText-Puffer zurückgegebene Fehlermeldung beschreibt den Fehler und seine Ursache.
HY001 Fehler bei der Speicherbelegung Der Treiber konnte keinen Arbeitsspeicher zuordnen, der für die Unterstützung der Ausführung oder Fertigstellung der Funktion erforderlich ist.
HY003 Programmtyp außerhalb des Bereichs (DM) Das Argument TargetType war kein gültiger Datentyp, SQL_C_DEFAULT, SQL_ARD_TYPE (im Falle des Abrufens von Spaltendaten) oder SQL_APD_TYPE (beim Abrufen von Parameterdaten).

(DM) Das Argument Col_or_Param_Num war 0, und das Argument TargetType wurde nicht für ein Lesezeichen mit fester Länge oder SQL_C_VARBOOKMARK für ein Lesezeichen mit variabler Länge SQL_C_BOOKMARK.
HY008 Vorgang abgebrochen Die asynchrone Verarbeitung wurde für statementHandle aktiviert. Die Funktion wurde aufgerufen, und bevor die Ausführung abgeschlossen war, wurde SQLCancel oder SQLCancelHandle für die StatementHandle aufgerufen, und dann wurde die Funktion erneut für statementHandle aufgerufen.

Die Funktion wurde aufgerufen, und bevor sie die Ausführung abgeschlossen hat, wurde SQLCancel oder SQLCancelHandle für die StatementHandle aus einem anderen Thread in einer Multithreadanwendung aufgerufen, und dann wurde die Funktion erneut für statementHandle aufgerufen.
HY009 Ungültige Verwendung des NULL-Zeigers (DM) Das Argument TargetValuePtr war ein NULL-Zeiger.
HY010 Funktionssequenzfehler (DM) Der angegebene StatementHandle befand sich nicht im Ausführungszustand. Die Funktion wurde aufgerufen, ohne zuerst SQLExecDirect, SQLExecute oder eine Katalogfunktion aufzurufen.

(DM) Eine asynchron ausgeführte Funktion wurde für das Verbindungshandle aufgerufen, das dem StatementHandle zugeordnet ist. Diese asynchrone Funktion wurde noch ausgeführt, als die FUNKTION SQLGetData aufgerufen wurde.

(DM) Eine asynchron ausgeführte Funktion (nicht diese) wurde für das StatementHandle aufgerufen und wurde noch ausgeführt, als diese Funktion aufgerufen wurde.

(DM) SQLExecute, SQLExecDirect, SQLBulkOperations oder SQLSetPos wurde für statementHandle aufgerufen und SQL_NEED_DATA zurückgegeben. Diese Funktion wurde aufgerufen, bevor Daten für alle Daten bei der Ausführungsparameter oder -spalten gesendet wurden.

(DM) Das StatementHandle befand sich in einem ausgeführten Zustand, aber es wurde kein Resultset dem StatementHandle zugeordnet.

Ein Aufruf von SQLExeceute, SQLExecDirect oder SQLMoreResults hat SQL_PARAM_DATA_AVAILABLE zurückgegeben, aber SQLGetData wurde anstelle von SQLParamData aufgerufen.
HY013 Fehler bei der Speicherverwaltung Der Funktionsaufruf konnte nicht verarbeitet werden, weil auf die zugrunde liegenden Speicherobjekte nicht zugegriffen werden konnte, möglicherweise aufgrund von geringen Arbeitsspeicherbedingungen.
HY090 Ungültige Zeichenfolgen- oder Pufferlänge (DM) Der für das Argument BufferLength angegebene Wert war kleiner als 0.

Der für das Argument BufferLength angegebene Wert war kleiner als 4, das argument Col_or_Param_Num wurde auf 0 festgelegt, und der Treiber war ein ODBC 2*.x*-Treiber.
HY109 Ungültige Cursorposition Der Cursor wurde (von SQLSetPos, SQLFetch, SQLFetchScroll oder SQLBulkOperations) in einer Zeile positioniert, die gelöscht wurde oder nicht abgerufen werden konnte.

Der Cursor war ein vorwärts gerichteter Cursor, und die Rowsetgröße war größer als eins.
HY117 Die Verbindung wird aufgrund eines unbekannten Transaktionsstatus angehalten. Nur trenn- und schreibgeschützte Funktionen sind zulässig. (DM) Weitere Informationen zum angehaltenen Zustand finden Sie unter SQLEndTran-Funktion.
HYC00 Optionales Feature nicht implementiert Der Treiber oder die Datenquelle unterstützt die Verwendung von SQLGetData mit mehreren Zeilen in SQLFetchScroll nicht. Diese Beschreibung gilt nicht für Treiber, die die SQL_GD_BLOCK Bitmaske für die Option SQL_GETDATA_EXTENSIONS in SQLGetInfo zurückgeben.

Der Treiber oder die Datenquelle unterstützt nicht die Konvertierung, die durch die Kombination des Arguments TargetType und des SQL-Datentyps der entsprechenden Spalte angegeben wird. Dieser Fehler tritt nur auf, wenn der SQL-Datentyp der Spalte einem treiberspezifischen SQL-Datentyp zugeordnet wurde.

Der Treiber unterstützt nur ODBC 2*.x*, und das Argument TargetType lautete eines der folgenden:

SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT

und alle Intervall-C-Datentypen, die unter C-Datentypen in Anhang D: Datentypen aufgeführt sind.

Der Treiber unterstützt nur ODBC-Versionen vor 3.50, und das Argument TargetType wurde SQL_C_GUID.
HYT01 Verbindungstimeout abgelaufen Der Zeitraum für das Verbindungstimeout ist abgelaufen, bevor die Datenquelle auf die Anforderung geantwortet hat. Der Verbindungstimeoutzeitraum wird über SQLSetConnectAttr festgelegt, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Treiber unterstützt diese Funktion nicht. (DM) Der Treiber, der dem StatementHandle entspricht, unterstützt die Funktion nicht.
IM017 Abruf ist im asynchronen Benachrichtigungsmodus deaktiviert. Wenn das Benachrichtigungsmodell verwendet wird, wird die Abfrage deaktiviert.
IM018 SQLCompleteAsync wurde nicht aufgerufen, um den vorherigen asynchronen Vorgang für dieses Handle abzuschließen. Wenn der vorherige Funktionsaufruf für das Handle SQL_STILL_EXECUTING zurückgibt und der Benachrichtigungsmodus aktiviert ist, muss SQLCompleteAsync für das Handle aufgerufen werden, um die Nachverarbeitung durchzuführen und den Vorgang abzuschließen.

Kommentare

SQLGetData gibt die Daten in einer angegebenen Spalte zurück. SQLGetData kann nur aufgerufen werden, nachdem eine oder mehrere Zeilen von SQLFetch, SQLFetchScroll oder SQLExtendedFetch aus dem Resultset abgerufen wurden. Wenn Daten mit variabler Länge zu groß sind, um in einem einzelnen Aufruf von SQLGetData zurückgegeben zu werden (aufgrund einer Einschränkung in der Anwendung), kann SQLGetData sie in Teilen abrufen. Es ist möglich, einige Spalten in einer Zeile zu binden und SQLGetData für andere aufzurufen, obwohl dies einigen Einschränkungen unterliegt. Weitere Informationen finden Sie unter Abrufen langer Daten.

Informationen zur Verwendung von SQLGetData mit gestreamten Ausgabeparametern finden Sie unter Abrufen von Ausgabeparametern mithilfe von SQLGetData.

Verwenden von SQLGetData

Wenn der Treiber keine Erweiterungen für SQLGetData unterstützt, kann die Funktion Daten nur für ungebundene Spalten zurückgeben, deren Zahl größer als die der letzten gebundenen Spalte ist. Darüber hinaus muss innerhalb einer Datenzeile der Wert des Col_or_Param_Num-Arguments in jedem Aufruf von SQLGetData größer oder gleich dem Wert von Col_or_Param_Num im vorherigen Aufruf sein. Das heißt, Daten müssen in erhöhter Reihenfolge der Spaltennummern abgerufen werden. Wenn schließlich keine Erweiterungen unterstützt werden, kann SQLGetData nicht aufgerufen werden, wenn die Rowsetgröße größer als 1 ist.

Autofahrer können diese Einschränkungen lockern. Um zu bestimmen, welche Einschränkungen ein Treiber lockert, ruft eine Anwendung SQLGetInfo mit einer der folgenden SQL_GETDATA_EXTENSIONS Optionen auf:

  • SQL_GD_OUTPUT_PARAMS = SQLGetData kann aufgerufen werden, um Ausgabeparameterwerte zurückzugeben. Weitere Informationen finden Sie unter Abrufen von Ausgabeparametern mithilfe von SQLGetData.

  • SQL_GD_ANY_COLUMN. Wenn diese Option zurückgegeben wird, kann SQLGetData für jede ungebundene Spalte aufgerufen werden, einschließlich der Spalten vor der letzten gebundenen Spalte.

  • SQL_GD_ANY_ORDER. Wenn diese Option zurückgegeben wird, kann SQLGetData für ungebundene Spalten in beliebiger Reihenfolge aufgerufen werden.

  • SQL_GD_BLOCK. Wenn diese Option von SQLGetInfo für den SQL_GETDATA_EXTENSIONS InfoType zurückgegeben wird, unterstützt der Treiber Aufrufe von SQLGetData, wenn die Rowsetgröße größer als 1 ist, und die Anwendung kann SQLSetPos mit der option SQL_POSITION aufrufen, um den Cursor vor dem Aufruf von SQLGetData auf die richtige Zeile zu positionieren.

  • SQL_GD_BOUND. Wenn diese Option zurückgegeben wird, kann SQLGetData sowohl für gebundene Spalten als auch für ungebundene Spalten aufgerufen werden.

Es gibt zwei Ausnahmen von diesen Einschränkungen und die Fähigkeit eines Fahrers, sie zu lockern. Erstens sollte SQLGetData niemals für einen Vorwärtscursor aufgerufen werden, wenn die Rowsetgröße größer als 1 ist. Zweitens: Wenn ein Treiber Lesezeichen unterstützt, muss er immer die Möglichkeit unterstützen , SQLGetData für Spalte 0 aufzurufen, auch wenn er es Anwendungen nicht erlaubt , SQLGetData für andere Spalten vor der letzten gebundenen Spalte aufzurufen. (Wenn eine Anwendung mit einem ODBC 2*.x*-Treiber arbeitet, SQLGetData gibt erfolgreich ein Lesezeichen zurück, wenn nach einem Aufruf von SQLFetch mit Col_or_Param_Num gleich 0 aufgerufen wird, da SQLFetch vom ODBC 3*.x*-Treiber-Manager sqlExtendedFetch mit einer FetchOrientation von SQL_FETCH_NEXT und SQLGetData mit dem Col_or_Param_Num 0 vom ODBC 3*.x*-Treiber-Manager sqlGetStmtOption mit einem zugeordnet wird. fOption von SQL_GET_BOOKMARK.)

SQLGetData kann nicht verwendet werden, um das Lesezeichen für eine Gerade eingefügte Zeile abzurufen, indem SQLBulkOperations mit der Option SQL_ADD aufgerufen wird, da der Cursor nicht in der Zeile positioniert ist. Eine Anwendung kann das Lesezeichen für eine solche Zeile abrufen, indem sie spalte 0 bindet, bevor SQLBulkOperations mit SQL_ADD aufgerufen wird. In diesem Fall gibt SQLBulkOperations das Lesezeichen im gebundenen Puffer zurück. SQLFetchScroll kann dann mit SQL_FETCH_BOOKMARK aufgerufen werden, um den Cursor in dieser Zeile neu zu positionieren.

Wenn das TargetType-Argument ein Intervalldatentyp ist, werden für die Daten die Standardgenauigkeit für das führende Intervall (2) und die Standardgenauigkeit von Intervallsekunden (6) verwendet, wie sie in den Feldern SQL_DESC_DATETIME_INTERVAL_PRECISION bzw. SQL_DESC_PRECISION der ARD festgelegt sind. Wenn das Argument TargetType ein SQL_C_NUMERIC Datentyp ist, werden für die Daten die Standardgenauigkeit (treiberdefiniert) und die Standardskalierung (0) verwendet, wie sie in den Feldern SQL_DESC_PRECISION und SQL_DESC_SCALE der ARD festgelegt sind. Wenn eine Standardgenauigkeit oder -skalierung nicht geeignet ist, sollte die Anwendung das entsprechende Deskriptorfeld explizit durch einen Aufruf von SQLSetDescField oder SQLSetDescRec festlegen. Es kann das feld SQL_DESC_CONCISE_TYPE auf SQL_C_NUMERIC festlegen und SQLGetData mit dem TargetType-Argument SQL_ARD_TYPE aufrufen, was dazu führt, dass die Genauigkeits- und Skalierungswerte in den Deskriptorfeldern verwendet werden.

Hinweis

In ODBC 2*.x* legen Anwendungen TargetType auf SQL_C_DATE, SQL_C_TIME oder SQL_C_TIMESTAMP fest, um anzugeben, dass *TargetValuePtr eine Datums-, Uhrzeit- oder Zeitstempelstruktur ist. In ODBC 3*.x* legen Anwendungen TargetType auf SQL_C_TYPE_DATE, SQL_C_TYPE_TIME oder SQL_C_TYPE_TIMESTAMP fest. Der Treiber-Manager erstellt bei Bedarf geeignete Zuordnungen basierend auf der Anwendung und der Treiberversion.

Abrufen von Variable-Length Daten in Teilen

SQLGetData kann verwendet werden, um Daten aus einer Spalte abzurufen, die Daten variabler Länge in Teilen enthält, d. h. wenn der Bezeichner des SQL-Datentyps der Spalte SQL_CHAR, SQL_VARCHAR, SQL_LONGVARCHAR, SQL_WCHAR, SQL_WVARCHAR, SQL_WLONGVARCHAR, SQL_BINARY, SQL_VARBINARY, SQL_LONGVARBINARY oder ein treiberspezifischer Bezeichner für einen Typ mit variabler Länge ist.

Um Daten aus einer Spalte in Teilen abzurufen, ruft die Anwendung SQLGetData mehrmals hintereinander für dieselbe Spalte auf. Bei jedem Aufruf gibt SQLGetData den nächsten Teil der Daten zurück. Es liegt an der Anwendung, die Teile neu zusammenzubauen, wobei darauf geachtet wird, dass das NULL-Terminierungszeichen aus zwischengeschalteten Teilen der Zeichendaten entfernt wird. Wenn mehr Daten zurückgegeben werden müssen oder nicht genügend Puffer für das Abbruchzeichen zugewiesen wurde, gibt SQLGetData SQL_SUCCESS_WITH_INFO und SQLSTATE 01004 (Daten abgeschnitten) zurück. Wenn der letzte Teil der Daten zurückgegeben wird, gibt SQLGetData SQL_SUCCESS zurück. Weder SQL_NO_TOTAL noch null kann beim letzten gültigen Aufruf zum Abrufen von Daten aus einer Spalte zurückgegeben werden, da die Anwendung dann nicht wissen kann, wie viele der Daten im Anwendungspuffer gültig sind. Wenn SQLGetData danach aufgerufen wird, wird SQL_NO_DATA zurückgegeben. Weitere Informationen finden Sie im nächsten Abschnitt unter Abrufen von Daten mit SQLGetData.

Lesezeichen mit variabler Länge können von SQLGetData in Teilen zurückgegeben werden. Wie bei anderen Daten gibt ein Aufruf von SQLGetData zum Zurückgeben von Lesezeichen variabler Länge in Teilen SQLSTATE 01004 (Zeichenfolgendaten, rechts abgeschnitten) und SQL_SUCCESS_WITH_INFO zurück, wenn mehr Daten zurückgegeben werden müssen. Dies unterscheidet sich von dem, wenn ein Lesezeichen mit variabler Länge durch einen Aufruf von SQLFetch oder SQLFetchScroll abgeschnitten wird, der SQL_ERROR und SQLSTATE 22001 (Zeichenfolgendaten, rechts abgeschnitten) zurückgibt.

SQLGetData kann nicht verwendet werden, um Daten mit fester Länge in Teilen zurückzugeben. Wenn SQLGetData mehrmals in einer Zeile für eine Spalte mit Daten fester Länge aufgerufen wird, gibt es SQL_NO_DATA für alle Aufrufe nach dem ersten zurück.

Abrufen gestreamter Ausgabeparameter

Wenn ein Treiber gestreamte Ausgabeparameter unterstützt, kann eine Anwendung SQLGetData mit einem kleinen Puffer mehrmals aufrufen, um einen großen Parameterwert abzurufen. Weitere Informationen zu gestreamten Ausgabeparametern finden Sie unter Abrufen von Ausgabeparametern mithilfe von SQLGetData.

Abrufen von Daten mit SQLGetData

Um Daten für die angegebene Spalte zurückzugeben, führt SQLGetData die folgenden Schritte aus:

  1. Gibt SQL_NO_DATA zurück, wenn bereits alle Daten für die Spalte zurückgegeben wurden.

  2. Legt *StrLen_or_IndPtr auf SQL_NULL_DATA fest, wenn die Daten NULL sind. Wenn die Daten NULL sind und StrLen_or_IndPtr ein NULL-Zeiger war, gibt SQLGetData SQLSTATE 22002 zurück (Indikatorvariable erforderlich, aber nicht angegeben).

    Wenn die Daten für die Spalte nicht NULL sind, fährt SQLGetData mit Schritt 3 fort.

  3. Wenn das SQL_ATTR_MAX_LENGTH-Anweisungsattribut auf einen Wert ungleich null festgelegt ist, die Spalte Zeichen- oder Binärdaten enthält und SQLGetData zuvor nicht für die Spalte aufgerufen wurde, werden die Daten auf SQL_ATTR_MAX_LENGTH Bytes abgeschnitten.

    Hinweis

    Das SQL_ATTR_MAX_LENGTH-Anweisungsattribut dient zur Verringerung des Netzwerkdatenverkehrs. Sie wird in der Regel von der Datenquelle implementiert, wodurch die Daten abgeschnitten werden, bevor sie über das Netzwerk zurückgegeben werden. Treiber und Datenquellen sind für die Unterstützung nicht erforderlich. Um sicherzustellen, dass Daten auf eine bestimmte Größe abgeschnitten werden, sollte eine Anwendung daher einen Puffer dieser Größe zuordnen und die Größe im Argument BufferLength angeben.

  4. Konvertiert die Daten in den in TargetType angegebenen Typ. Die Daten erhalten die Standardgenauigkeit und -skalierung für diesen Datentyp. Wenn TargetType SQL_ARD_TYPE ist, wird der Datentyp im feld SQL_DESC_CONCISE_TYPE der ARD verwendet. Wenn TargetType SQL_ARD_TYPE ist, erhalten die Daten je nach Datentyp im Feld SQL_DESC_CONCISE_TYPE die Genauigkeit und Skalierung in den Feldern SQL_DESC_DATETIME_INTERVAL_PRECISION, SQL_DESC_PRECISION und SQL_DESC_SCALE der ARD. Wenn eine Standardgenauigkeit oder -skalierung nicht geeignet ist, sollte die Anwendung das entsprechende Deskriptorfeld explizit durch einen Aufruf von SQLSetDescField oder SQLSetDescRec festlegen.

  5. Wenn die Daten in einen Datentyp mit variabler Länge konvertiert wurden, z. B. zeichen oder binär, überprüft SQLGetData , ob die Länge der Daten BufferLength überschreitet. Wenn die Länge der Zeichendaten (einschließlich des NULL-Terminierungszeichens) BufferLength überschreitet, schneidet SQLGetData die Daten in BufferLength ab, abzüglich der Länge eines NULL-Terminierungszeichens. Anschließend werden die Daten mit NULL beendet. Wenn die Länge der Binärdaten die Länge des Datenpuffers überschreitet, schneidet SQLGetData sie in BufferLength-Bytes ab.

    Wenn der bereitgestellte Datenpuffer zu klein ist, um das NULL-Terminierungszeichen zu enthalten, gibt SQLGetData SQL_SUCCESS_WITH_INFO und SQLSTATE 01004 zurück.

    SQLGetData schneidet niemals Daten ab, die in Datentypen mit fester Länge konvertiert werden. Dabei wird immer davon ausgegangen, dass die Länge von *TargetValuePtr die Größe des Datentyps ist.

  6. Platziert die konvertierten (und möglicherweise abgeschnittenen) Daten in *TargetValuePtr. Beachten Sie, dass SQLGetData keine Daten außerhalb der Zeile zurückgeben kann.

  7. Platziert die Länge der Daten in *StrLen_or_IndPtr. Wenn StrLen_or_IndPtr ein NULL-Zeiger war, gibt SQLGetData die Länge nicht zurück.

    • Bei Zeichen- oder Binärdaten ist dies die Länge der Daten nach der Konvertierung und vor dem Abschneiden aufgrund von BufferLength. Wenn der Treiber die Länge der Daten nach der Konvertierung nicht bestimmen kann, wie dies manchmal bei langen Daten der Fall ist, gibt er SQL_SUCCESS_WITH_INFO zurück und legt die Länge auf SQL_NO_TOTAL fest. (Der letzte Aufruf von SQLGetData muss immer die Länge der Daten zurückgeben, nicht null oder SQL_NO_TOTAL.) Wenn Daten aufgrund des SQL_ATTR_MAX_LENGTH-Anweisungsattributs abgeschnitten wurden, wird der Wert dieses Attributs - im Gegensatz zur tatsächlichen Länge - in *StrLen_or_IndPtr platziert. Dies liegt daran, dass dieses Attribut darauf ausgelegt ist, Daten auf dem Server vor der Konvertierung abzuschneiden, sodass der Treiber keine Möglichkeit hat, die tatsächliche Länge zu ermitteln. Wenn SQLGetData mehrmals hintereinander für dieselbe Spalte aufgerufen wird, ist dies die Länge der Daten, die zu Beginn des aktuellen Aufrufs verfügbar sind. Das heißt, die Länge nimmt mit jedem nachfolgenden Aufruf ab.

    • Bei allen anderen Datentypen ist dies die Länge der Daten nach der Konvertierung. Das heißt, es ist die Größe des Typs, in den die Daten konvertiert wurden.

  8. Wenn die Daten während der Konvertierung ohne Bedeutungsverlust abgeschnitten werden (z. B. wird die reelle Zahl 1.234 abgeschnitten, wenn sie in die ganze Zahl 1 konvertiert wird) oder weil BufferLength zu klein ist (z. B. wird die Zeichenfolge "abcdef" in einen 4-Byte-Puffer eingefügt), gibt SQLGetData SQLSTATE 01004 (Daten abgeschnitten) und SQL_SUCCESS_WITH_INFO zurück. Wenn Daten ohne Bedeutungsverlust aufgrund des SQL_ATTR_MAX_LENGTH-Anweisungsattributs abgeschnitten werden, gibt SQLGetData SQL_SUCCESS zurück und gibt SQLSTATE 01004 (Daten abgeschnitten) nicht zurück.

Der Inhalt des gebundenen Datenpuffers (wenn SQLGetData für eine gebundene Spalte aufgerufen wird) und der Längen-/Indikatorpuffer sind nicht definiert, wenn SQLGetData nicht SQL_SUCCESS oder SQL_SUCCESS_WITH_INFO zurückgibt.

Nachfolgende Aufrufe von SQLGetData rufen Daten aus der zuletzt angeforderten Spalte ab. vorherige Offsets werden ungültig. Wenn beispielsweise die folgende Sequenz ausgeführt wird:

SQLGetData(icol=n), SQLGetData(icol=m), SQLGetData(icol=n)  

Der zweite Aufruf von SQLGetData(icol=n) ruft Daten vom Anfang der Spalte n ab. Ein Offset in den Daten aufgrund früherer Aufrufe von SQLGetData für die Spalte ist nicht mehr gültig.

Deskriptoren und SQLGetData

SQLGetData interagiert nicht direkt mit Deskriptorfeldern.

Wenn TargetType SQL_ARD_TYPE ist, wird der Datentyp im feld SQL_DESC_CONCISE_TYPE der ARD verwendet. Wenn TargetType entweder SQL_ARD_TYPE oder SQL_C_DEFAULT ist, erhalten die Daten je nach Datentyp im Feld SQL_DESC_CONCISE_TYPE die Genauigkeit und Skalierung in den Feldern SQL_DESC_DATETIME_INTERVAL_PRECISION, SQL_DESC_PRECISION und SQL_DESC_SCALE der ARD.

Codebeispiel

Im folgenden Beispiel führt eine Anwendung eine SELECT-Anweisung aus, um ein Resultset der Kunden-IDs, Namen und Telefonnummern nach Name, ID und Telefonnummer zurückzugeben. Für jede Datenzeile wird SQLFetch aufgerufen, um den Cursor in die nächste Zeile zu positionieren. Es ruft SQLGetData auf, um die abgerufenen Daten abzurufen. die Puffer für die Daten und die zurückgegebene Anzahl von Bytes werden im Aufruf von SQLGetData angegeben. Schließlich werden der Name, die ID und die Telefonnummer jedes Mitarbeiters ausgegeben.

#define NAME_LEN 50  
#define PHONE_LEN 50  
  
SQLCHAR      szName[NAME_LEN], szPhone[PHONE_LEN];  
SQLINTEGER   sCustID, cbName, cbAge, cbBirthday;  
SQLRETURN    retcode;  
SQLHSTMT     hstmt;  
  
retcode = SQLExecDirect(hstmt,  
   "SELECT CUSTID, NAME, PHONE FROM CUSTOMERS ORDER BY 2, 1, 3",  
   SQL_NTS);  
  
if (retcode == SQL_SUCCESS) {  
   while (TRUE) {  
      retcode = SQLFetch(hstmt);  
      if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO) {  
         show_error();  
      }  
      if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){  
  
         /* Get data for columns 1, 2, and 3 */  
  
         SQLGetData(hstmt, 1, SQL_C_ULONG, &sCustID, 0, &cbCustID);  
         SQLGetData(hstmt, 2, SQL_C_CHAR, szName, NAME_LEN, &cbName);  
         SQLGetData(hstmt, 3, SQL_C_CHAR, szPhone, PHONE_LEN,  
            &cbPhone);  
  
         /* Print the row of data */  
  
         fprintf(out, "%-5d %-*s %*s", sCustID, NAME_LEN-1, szName,   
            PHONE_LEN-1, szPhone);  
      } else {  
         break;  
      }  
   }  
}  
Informationen über Finden Sie unter
Zuweisen von Speicher für eine Spalte in einem Resultset SQLBindCol
Ausführen von Massenvorgängen, die sich nicht auf die Position des Blockcursors beziehen SQLBulkOperations
Abbrechen der Anweisungsverarbeitung SQLCancel
Ausführen einer SQL-Anweisung SQLExecDirect
Ausführen einer vorbereiteten SQL-Anweisung SQLExecute
Abrufen eines Datenblocks oder Scrollen durch ein Resultset SQLFetchScroll
Abrufen einer einzelnen Datenzeile oder eines Datenblocks in einer vorwärtsgerichteten Richtung SQLFetch
Senden von Parameterdaten zur Ausführungszeit SQLPutData
Positionieren des Cursors, Aktualisieren von Daten im Rowset oder Aktualisieren oder Löschen von Daten im Rowset SQLSetPos

Weitere Informationen

ODBC-API-Referenz
ODBC-Headerdateien
Abrufen von Ausgabeparametern mithilfe von SQLGetData