SQLBindCol-Funktion

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

Zusammenfassung
SQLBindCol bindet Anwendungsdatenpuffer an Spalten im Resultset.

Syntax

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

Argumente

StatementHandle
[Eingabe] Anweisungshandle.

ColumnNumber
[Eingabe] Nummer der zu bindenden Resultsetspalte. Spalten werden in erhöhter Spaltenreihenfolge nummeriert, beginnend bei 0, wobei Spalte 0 die Lesezeichenspalte ist. Wenn keine Lesezeichen verwendet werden , d. h. das Attribut der SQL_ATTR_USE_BOOKMARKS-Anweisung auf SQL_UB_OFF festgelegt ist, beginnen Die Spaltennummern bei 1.

TargetType
[Eingabe] Der Bezeichner des C-Datentyps des *TargetValuePtr-Puffers . Beim Abrufen von Daten aus der Datenquelle mit SQLFetch, SQLFetchScroll, SQLBulkOperations oder SQLSetPos konvertiert der Treiber die Daten in diesen Typ. Wenn Daten mit SQLBulkOperations oder SQLSetPos an die Datenquelle gesendet werden, konvertiert der Treiber die Daten aus diesem Typ. Eine Liste der gültigen C-Datentypen und Typbezeichner finden Sie im Abschnitt C-Datentypen in Anhang D: Datentypen.

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 SQL_C_NUMERIC ist, werden die Standardgenauigkeit (treiberdefiniert) und die Standardskalierung (0) wie in den Feldern SQL_DESC_PRECISION und SQL_DESC_SCALE der ARD festgelegt, für die Daten verwendet. Wenn eine Standardgenauigkeit oder -skalierung nicht geeignet ist, sollte die Anwendung das entsprechende Deskriptorfeld explizit durch einen Aufruf von SQLSetDescField oder SQLSetDescRec festlegen.

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

TargetValuePtr
[Verzögerte Eingabe/Ausgabe] Zeiger auf den Datenpuffer, der an die Spalte gebunden werden soll. SQLFetch und SQLFetchScroll geben Daten in diesem Puffer zurück. SQLBulkOperations gibt Daten in diesem Puffer zurück, wenn Operation SQL_FETCH_BY_BOOKMARK ist. Es ruft Daten aus diesem Puffer ab, wenn Operation SQL_ADD oder SQL_UPDATE_BY_BOOKMARK ist. SQLSetPos gibt Daten in diesem Puffer zurück, wenn Operation SQL_REFRESH ist. Es ruft Daten aus diesem Puffer ab, wenn Operation SQL_UPDATE ist.

Wenn TargetValuePtr ein NULL-Zeiger ist, hebt der Treiber die Bindung des Datenpuffers für die Spalte auf. Eine Anwendung kann die Bindung aller Spalten aufheben, indem SQLFreeStmt mit der Option SQL_UNBIND aufgerufen wird. Eine Anwendung kann die Bindung des Datenpuffers für eine Spalte aufheben, hat aber weiterhin einen Längen-/Indikatorpuffer für die Spalte gebunden, wenn das TargetValuePtr-Argument im Aufruf von SQLBindCol ein NULL-Zeiger ist, aber das argument StrLen_or_IndPtr ein gültiger Wert ist.

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

Der Treiber verwendet BufferLength , um zu vermeiden, dass das Schreiben über das Ende des *TargetValuePtr-Puffers hinausgeht, wenn Daten mit variabler Länge zurückgegeben werden, z. B. Zeichen- oder Binärdaten. Beachten Sie, dass der Treiber das NULL-Terminierungszeichen zählt, wenn er Zeichendaten an *TargetValuePtr zurückgibt. *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.

SQLBindCol gibt SQLSTATE HY090 (ungültige Zeichenfolgen- oder Pufferlänge) zurück, wenn BufferLength kleiner als 0 ist, aber nicht, wenn BufferLength 0 ist. Wenn TargetType jedoch einen Zeichentyp angibt, sollte eine Anwendung BufferLength nicht auf 0 festlegen, da ISO CLI-konforme Treiber in diesem Fall SQLSTATE HY090 (ungültige Zeichenfolgen- oder Pufferlänge) zurückgeben.

StrLen_or_IndPtr
[Verzögerte Eingabe/Ausgabe] Zeiger auf den Längen-/Indikatorpuffer, der an die Spalte gebunden werden soll. SQLFetch und SQLFetchScroll geben einen Wert in diesem Puffer zurück. SQLBulkOperations ruft einen Wert aus diesem Puffer ab, wenn Operation SQL_ADD, SQL_UPDATE_BY_BOOKMARK oder SQL_DELETE_BY_BOOKMARK ist. SQLBulkOperations gibt einen Wert in diesem Puffer zurück, wenn Operation SQL_FETCH_BY_BOOKMARK ist. SQLSetPos gibt einen Wert in diesem Puffer zurück, wenn Operation SQL_REFRESH ist. Es ruft einen Wert aus diesem Puffer ab, wenn Operation SQL_UPDATE ist.

SQLFetch, SQLFetchScroll, SQLBulkOperations und SQLSetPos können die folgenden Werte im Längen-/Indikatorpuffer zurückgeben:

  • Die Länge der zurückzugebenden Daten

  • SQL_NO_TOTAL

  • SQL_NULL_DATA

Die Anwendung kann die folgenden Werte in den Längen-/Indikatorpuffer für die Verwendung mit SQLBulkOperations oder SQLSetPos einfügen:

  • Die Länge der gesendeten Daten

  • SQL_NTS

  • SQL_NULL_DATA

  • SQL_DATA_AT_EXEC

  • Das Ergebnis des SQL_LEN_DATA_AT_EXEC-Makros

  • SQL_COLUMN_IGNORE

Wenn der Indikatorpuffer und der Längenpuffer separate Puffer sind, kann der Indikatorpuffer nur SQL_NULL_DATA zurückgeben, während der Längenpuffer alle anderen Werte zurückgeben kann.

Weitere Informationen finden Sie unter SQLBulkOperations-Funktion, SQLFetch-Funktion, SQLSetPos-Funktion und Verwenden von Längen-/Indikatorwerten.

Wenn StrLen_or_IndPtr ein NULL-Zeiger ist, wird kein Längen- oder Indikatorwert verwendet. Dies ist ein Fehler beim Abrufen von Daten, und die Daten sind NULL.

Informationen zur Ausführung Ihrer Anwendung unter einem 64-Bit-Betriebssystem finden Sie unter ODBC 64-Bit-Informationen.

Gibt zurück

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR oder SQL_INVALID_HANDLE.

Diagnose

Wenn SQLBindCol 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 in der Regel von SQLBindCol 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.)
07006 Verletzung des eingeschränkten Datentyp-Attributs (DM) Das ColumnNumber-Argument war 0, und das Argument TargetType wurde nicht SQL_C_BOOKMARK oder SQL_C_VARBOOKMARK.
07009 Ungültiger Deskriptorindex Der für das Argument ColumnNumber angegebene Wert überschreitet die maximale Anzahl von Spalten im Resultset.
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 arbeitsspeicher nicht zuordnen, der zur Unterstützung der Ausführung oder Fertigstellung der Funktion erforderlich ist.
HY003 Ungültiger Anwendungspuffertyp Das Argument TargetType war weder ein gültiger Datentyp noch SQL_C_DEFAULT.
HY010 Funktionssequenzfehler (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 SQLBindCol aufgerufen wurde.

(DM) SQLExecute, SQLExecDirect oder SQLMoreResults wurde für statementHandle aufgerufen und SQL_PARAM_DATA_AVAILABLE zurückgegeben. Diese Funktion wurde aufgerufen, bevor Daten für alle gestreamten Parameter abgerufen wurden.

(DM) Eine asynchron ausgeführte Funktion wurde für 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.
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.

(DM) Der Treiber war ein ODBC 2. x-Treiber , das ColumnNumber-Argument wurde auf 0 festgelegt, und der für das Argument BufferLength angegebene Wert war nicht gleich 4.
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 Konvertierung nicht, die durch die Kombination aus dem Argument TargetType und dem treiberspezifischen SQL-Datentyp der entsprechenden Spalte angegeben wird.

Das Argument ColumnNumber war 0, und der Treiber unterstützt keine Lesezeichen.

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 Der StatementHandle zugeordnete Treiber unterstützt die Funktion nicht.

Kommentare

SQLBindCol wird verwendet, um Spalten im Resultset Datenpuffern und Längen-/Indikatorpuffern in der Anwendung zuzuordnen oder zu binden . Wenn die Anwendung SQLFetch, SQLFetchScroll oder SQLSetPos aufruft , um Daten abzurufen, gibt der Treiber die Daten für die gebundenen Spalten in den angegebenen Puffern zurück. Weitere Informationen finden Sie unter SQLFetch-Funktion. Wenn die Anwendung SQLBulkOperations aufruft , um eine Zeile oder SQLSetPos zum Aktualisieren einer Zeile einzufügen, ruft der Treiber die Daten für die gebundenen Spalten aus den angegebenen Puffern ab. weitere Informationen finden Sie unter SQLBulkOperations-Funktion oder SQLSetPos-Funktion. Weitere Informationen zur Bindung finden Sie unter Abrufen von Ergebnissen (Basic).

Beachten Sie, dass Spalten nicht gebunden werden müssen, um Daten aus ihnen abzurufen. Eine Anwendung kann auch SQLGetData aufrufen, um Daten aus Spalten abzurufen. Obwohl es möglich ist, einige Spalten in einer Zeile zu binden und SQLGetData für andere aufzurufen, unterliegt dies einigen Einschränkungen. Weitere Informationen finden Sie unter SQLGetData.

Binden, Aufheben der Bindung und Erneute Bindung von Spalten

Eine Spalte kann jederzeit gebunden, ungebunden oder reboundiert werden, auch nachdem Daten aus dem Resultset abgerufen wurden. Die neue Bindung wird wirksam, wenn eine Funktion, die Bindungen verwendet, das nächste Mal aufgerufen wird. Angenommen, eine Anwendung bindet die Spalten in einem Resultset und ruft SQLFetch auf. Der Treiber gibt die Daten in den gebundenen Puffern zurück. Angenommen, die Anwendung bindet die Spalten an einen anderen Satz von Puffern. Der Treiber platziert die Daten für die gerade abgerufene Zeile nicht in den neu gebundenen Puffern. Stattdessen wartet es, bis SQLFetch erneut aufgerufen wird, und platziert dann die Daten für die nächste Zeile in den neu gebundenen Puffern.

Hinweis

Das Anweisungsattribut SQL_ATTR_USE_BOOKMARKS sollte immer festgelegt werden, bevor eine Spalte an Spalte 0 gebunden wird. Dies ist nicht erforderlich, wird aber dringend empfohlen.

Binden von Spalten

Um eine Spalte zu binden, ruft eine Anwendung SQLBindCol auf und übergibt die Spaltennummer, den Typ, die Adresse und die Länge eines Datenpuffers sowie die Adresse eines Längen-/Indikatorpuffers. Informationen zur Verwendung dieser Adressen finden Sie weiter unten in diesem Abschnitt unter "Pufferadressen". Weitere Informationen zum Binden von Spalten finden Sie unter Verwenden von SQLBindCol.

Die Verwendung dieser Puffer wird verzögert; Das heißt, die Anwendung bindet sie in SQLBindCol , aber der Treiber greift von anderen Funktionen auf sie zu, nämlich SQLBulkOperations, SQLFetch, SQLFetchScroll oder SQLSetPos. Es liegt in der Verantwortung der Anwendung sicherzustellen, dass die in SQLBindCol angegebenen Zeiger gültig bleiben, solange die Bindung wirksam bleibt. Wenn die Anwendung zulässt, dass diese Zeiger ungültig werden ( z. B. einen Puffer freigibt) und dann eine Funktion aufruft, die ihre Gültigkeit erwartet, sind die Konsequenzen nicht definiert. Weitere Informationen finden Sie unter Verzögerte Puffer.

Die Bindung bleibt wirksam, bis sie durch eine neue Bindung ersetzt wird, die Spalte ungebunden ist oder die Anweisung freigegeben wird.

Aufheben der Bindung von Spalten

Um die Bindung einer einzelnen Spalte aufzuheben, ruft eine Anwendung SQLBindCol auf, wobei ColumnNumber auf die Nummer dieser Spalte und TargetValuePtr auf einen NULL-Zeiger festgelegt ist. Wenn ColumnNumber auf eine ungebundene Spalte verweist, gibt SQLBindCol weiterhin SQL_SUCCESS zurück.

Um die Bindung aller Spalten aufzuheben, ruft eine Anwendung SQLFreeStmt auf, wobei fOption auf SQL_UNBIND festgelegt ist. Dies kann auch erreicht werden, indem das SQL_DESC_COUNT Feld der ARD auf 0 festgelegt wird.

Erneutes Binden von Spalten

Eine Anwendung kann einen von zwei Vorgängen ausführen, um eine Bindung zu ändern:

  • Rufen Sie SQLBindCol auf, um eine neue Bindung für eine Spalte anzugeben, die bereits gebunden ist. Der Treiber überschreibt die alte Bindung mit der neuen Bindung.

  • Geben Sie einen Offset an, der der Pufferadresse hinzugefügt werden soll, die durch den Bindungsaufruf von SQLBindCol angegeben wurde. Weitere Informationen finden Sie im nächsten Abschnitt, "Bindungsoffsets".

Bindungsoffsets

Ein Bindungsoffset ist ein Wert, der den Adressen der Daten- und Längen-/Indikatorpuffer (wie im Argument TargetValuePtr und StrLen_or_IndPtr angegeben) hinzugefügt wird, bevor sie abgeleitet werden. Wenn Offsets verwendet werden, sind die Bindungen eine "Vorlage", wie die Puffer der Anwendung angeordnet sind, und die Anwendung kann diese "Vorlage" durch Ändern des Offsets in verschiedene Speicherbereiche verschieben. Da jeder Adresse in jeder Bindung derselbe Offset hinzugefügt wird, müssen die relativen Offsets zwischen Puffern für verschiedene Spalten innerhalb der einzelnen Puffersätze identisch sein. Dies gilt immer, wenn zeilenweise Bindung verwendet wird. Die Anwendung muss ihre Puffer sorgfältig anordnen, damit dies wahr ist, wenn eine spaltenweise Bindung verwendet wird.

Die Verwendung eines Bindungsoffsets hat im Grunde die gleiche Auswirkung wie das erneute Binden einer Spalte durch Aufrufen von SQLBindCol. Der Unterschied besteht darin, dass ein neuer Aufruf von SQLBindCol neue Adressen für den Datenpuffer und den Längen-/Indikatorpuffer angibt, während die Verwendung eines Bindungsoffsets die Adressen nicht ändert, sondern nur einen Offset hinzufügt. Die Anwendung kann jederzeit einen neuen Offset angeben, und dieser Offset wird immer den ursprünglich gebundenen Adressen hinzugefügt. Insbesondere wenn der Offset auf 0 festgelegt ist oder das Anweisungsattribut auf einen NULL-Zeiger festgelegt ist, verwendet der Treiber die ursprünglich gebundenen Adressen.

Um einen Bindungsoffset anzugeben, legt die Anwendung das SQL_ATTR_ROW_BIND_OFFSET_PTR-Anweisungsattribut auf die Adresse eines SQLINTEGER-Puffers fest. Bevor die Anwendung eine Funktion aufruft, die Bindungen verwendet, fügt sie einen Offset in Bytes in diesen Puffer ein. Um die Adresse des zu verwendenden Puffers zu bestimmen, fügt der Treiber den Offset der Adresse in der Bindung hinzu. Die Summe der Adresse und des Offsets muss eine gültige Adresse sein, aber die Adresse, der der Offset hinzugefügt wird, muss nicht gültig sein. Weitere Informationen zur Verwendung von Bindungsoffsets finden Sie weiter unten in diesem Abschnitt unter "Pufferadressen".

Binden von Arrays

Wenn die Rowsetgröße (der Wert des SQL_ATTR_ROW_ARRAY_SIZE-Anweisungsattributs) größer als 1 ist, bindet die Anwendung Arrays von Puffern anstelle einzelner Puffer. Weitere Informationen finden Sie unter Blockieren von Cursorn.

Die Anwendung kann Arrays auf zwei Arten binden:

  • Binden Sie ein Array an jede Spalte. Dies wird als spaltenweise Bindung bezeichnet, da jede Datenstruktur (Array) Daten für eine einzelne Spalte enthält.

  • Definieren Sie eine Struktur, die die Daten für eine ganze Zeile enthält, und binden Sie ein Array dieser Strukturen. Dies wird als zeilenweise Bindung bezeichnet, da jede Datenstruktur die Daten für eine einzelne Zeile enthält.

Jedes Array von Puffern muss mindestens so viele Elemente wie die Größe des Rowsets aufweisen.

Hinweis

Eine Anwendung muss überprüfen, ob die Ausrichtung gültig ist. Weitere Informationen zu Ausrichtungsüberlegungen finden Sie unter Ausrichtung.

Spaltenbezogenes Binden

Bei der spaltenweisen Bindung bindet die Anwendung separate Daten- und Längen-/Indikatorarrays an jede Spalte.

Um die spaltenbasierte Bindung zu verwenden, legt die Anwendung zunächst das Attribut der SQL_ATTR_ROW_BIND_TYPE-Anweisung auf SQL_BIND_BY_COLUMN fest. (Dies ist die Standardeinstellung.) Für jede spalte, die gebunden werden soll, führt die Anwendung die folgenden Schritte aus:

  1. Ordnet ein Datenpufferarray zu.

  2. Weist ein Array von Längen-/Indikatorpuffern zu.

    Hinweis

    Wenn die Anwendung bei Verwendung der spaltenweisen Bindung direkt in Deskriptoren schreibt, können separate Arrays für Längen- und Indikatordaten verwendet werden.

  3. Ruft SQLBindCol mit den folgenden Argumenten auf:

    • TargetType ist der Typ eines einzelnen Elements im Datenpufferarray.

    • TargetValuePtr ist die Adresse des Datenpufferarrays.

    • BufferLength ist die Größe eines einzelnen Elements im Datenpufferarray. Das BufferLength-Argument wird ignoriert, wenn es sich bei den Daten um Daten mit fester Länge handelt.

    • StrLen_or_IndPtr ist die Adresse des Längen-/Indikatorarrays.

Weitere Informationen zur Verwendung dieser Informationen finden Sie weiter unten in diesem Abschnitt unter "Pufferadressen". Weitere Informationen zur spaltenweisen Bindung finden Sie unter Column-Wise Binding.

Zeilenbezogenes Binden

In der zeilenweisen Bindung definiert die Anwendung eine Struktur, die Daten- und Längen-/Indikatorpuffer für jede zu gebundene Spalte enthält.

Um zeilenweise Bindung zu verwenden, führt die Anwendung die folgenden Schritte aus:

  1. Definiert eine Struktur, die eine einzelne Datenzeile (einschließlich Daten- und Längen-/Indikatorpuffern) enthält, und weist ein Array dieser Strukturen zu.

    Hinweis

    Wenn die Anwendung direkt in Deskriptoren schreibt, wenn zeilenweise Bindung verwendet wird, können separate Felder für Längen- und Indikatordaten verwendet werden.

  2. Legt das Attribut SQL_ATTR_ROW_BIND_TYPE-Anweisung auf die Größe der Struktur fest, die eine einzelne Datenzeile enthält, oder auf die Größe einer Instanz eines Puffers, an die die Ergebnisspalten gebunden werden. Die Länge muss Platz für alle gebundenen Spalten und alle Auffüllungen der Struktur oder des Puffers enthalten, um sicherzustellen, dass das Ergebnis auf den Anfang derselben Spalte in der nächsten Zeile zeigt, wenn die Adresse einer gebundenen Spalte mit der angegebenen Länge erhöht wird. Wenn Sie den Operator sizeof in ANSI C verwenden, ist dieses Verhalten garantiert.

  3. Ruft SQLBindCol mit den folgenden Argumenten für jede spalte auf, die gebunden werden soll:

    • TargetType ist der Typ des Datenpuffermembers, der an die Spalte gebunden werden soll.

    • TargetValuePtr ist die Adresse des Datenpufferelements im ersten Arrayelement.

    • BufferLength ist die Größe des Datenpuffermembers.

    • StrLen_or_IndPtr ist die Adresse des zu bindenden Längen-/Indikatorelements.

Weitere Informationen zur Verwendung dieser Informationen finden Sie weiter unten in diesem Abschnitt unter "Pufferadressen". Weitere Informationen zur spaltenweisen Bindung finden Sie unter Row-Wise Binding.

Pufferadressen

Die Pufferadresse ist die tatsächliche Adresse des Daten- oder Längen-/Indikatorpuffers. Der Treiber berechnet die Pufferadresse, bevor er in die Puffer schreibt (z. B. während der Abrufzeit). Sie wird anhand der folgenden Formel berechnet, die die Adressen verwendet, die in den Argumenten TargetValuePtr und StrLen_or_IndPtr , dem Bindungsoffset und der Zeilennummer angegeben sind:

Gebundene Adresse + Bindungsoffset + ((Zeilenzahl - 1) x Elementgröße)

wobei die Variablen der Formel wie in der folgenden Tabelle beschrieben definiert sind.

Variable BESCHREIBUNG
Gebundene Adresse Bei Datenpuffern die Adresse, die mit dem Argument TargetValuePtr in SQLBindCol angegeben wurde.

Bei Längen-/Indikatorpuffern die adresse, die mit dem argument StrLen_or_IndPtr in SQLBindCol angegeben ist. Weitere Informationen finden Sie unter "Zusätzliche Kommentare" im Abschnitt "Deskriptoren und SQLBindCol".

Wenn die gebundene Adresse 0 ist, wird kein Datenwert zurückgegeben, auch wenn die von der vorherigen Formel berechnete Adresse nichtzero ist.
Bindungsoffset Wenn zeilenweise Bindung verwendet wird, wird der Wert an der Adresse gespeichert, die mit dem attribut SQL_ATTR_ROW_BIND_OFFSET_PTR-Anweisung angegeben ist.

Wenn eine spaltenweise Bindung verwendet wird oder der Wert des SQL_ATTR_ROW_BIND_OFFSET_PTR-Anweisungsattributs ein NULL-Zeiger ist, ist Binding Offset 0.
Row Number Die 1-basierte Anzahl der Zeile im Rowset. Für Einzeilenabrufe, die standardmäßig sind, ist dies 1.
Elementgröße Die Größe eines Elements im gebundenen Array.

Wenn spaltenweise Bindung verwendet wird, ist dies sizeof(SQLINTEGER) für Längen-/Indikatorpuffer. Bei Datenpuffern ist dies der Wert des BufferLength-Arguments in SQLBindCol , wenn der Datentyp variable Länge hat, und die Größe des Datentyps, wenn der Datentyp eine feste Länge aufweist.

Wenn zeilenweise Bindung verwendet wird, ist dies der Wert des SQL_ATTR_ROW_BIND_TYPE-Anweisungsattributs sowohl für Daten- als auch für Längen-/Indikatorpuffer.

Deskriptoren und SQLBindCol

In den folgenden Abschnitten wird beschrieben, wie SQLBindCol mit Deskriptoren interagiert.

Achtung

Das Aufrufen von SQLBindCol für eine Anweisung kann sich auf andere Anweisungen auswirken. Dies tritt auf, wenn die der Anweisung zugeordnete ARD explizit zugeordnet ist und auch anderen Anweisungen zugeordnet ist. Da SQLBindCol den Deskriptor ändert, gelten die Änderungen für alle Anweisungen, denen dieser Deskriptor zugeordnet ist. Wenn dies nicht das erforderliche Verhalten ist, sollte die Anwendung diesen Deskriptor von den anderen Anweisungen trennen, bevor SQLBindCol aufgerufen wird.

Argumentzuordnungen

Konzeptionell führt SQLBindCol die folgenden Schritte nacheinander aus:

  1. Ruft SQLGetStmtAttr auf, um das ARD-Handle abzurufen.

  2. Ruft SQLGetDescField auf, um das SQL_DESC_COUNT Feld dieses Deskriptors abzurufen, und wenn der Wert im ColumnNumber-Argument den Wert von SQL_DESC_COUNT überschreitet, ruft SQLSetDescField auf, um den Wert von SQL_DESC_COUNT in ColumnNumber zu erhöhen.

  3. Ruft SQLSetDescField mehrmals auf, um den folgenden Feldern der ARD Werte zuzuweisen:

    • Legt SQL_DESC_TYPE und SQL_DESC_CONCISE_TYPE auf den Wert von TargetType fest. Wenn TargetType einer der präzisen Bezeichner eines datetime- oder Intervalluntertyps ist, wird SQL_DESC_TYPE auf SQL_DATETIME bzw. SQL_INTERVAL festgelegt; legt SQL_DESC_CONCISE_TYPE auf den präzisen Bezeichner fest; und legt SQL_DESC_DATETIME_INTERVAL_CODE auf die entsprechende datetime- oder Intervalluntercodierung fest.

    • Legt einen oder mehrere SQL_DESC_LENGTH, SQL_DESC_PRECISION, SQL_DESC_SCALE und SQL_DESC_DATETIME_INTERVAL_PRECISION entsprechend TargetType fest.

    • Legt das feld SQL_DESC_OCTET_LENGTH auf den Wert von BufferLength fest.

    • Legt das feld SQL_DESC_DATA_PTR auf den Wert von TargetValuePtr fest.

    • Legt das feld SQL_DESC_INDICATOR_PTR auf den Wert von StrLen_or_IndPtr fest. (Siehe folgenden Absatz.)

    • Legt das feld SQL_DESC_OCTET_LENGTH_PTR auf den Wert von StrLen_or_IndPtr fest. (Siehe folgenden Absatz.)

Die Variable, auf die sich das argument StrLen_or_IndPtr bezieht, wird sowohl für Indikator- als auch für Längeninformationen verwendet. Wenn ein Abruf auf einen NULL-Wert für die Spalte stößt, speichert er SQL_NULL_DATA in dieser Variablen. Andernfalls speichert sie die Datenlänge in dieser Variablen. Das Übergeben eines NULL-Zeigers als StrLen_or_IndPtr verhindert, dass der Abrufvorgang die Datenlänge zurückgibt, führt jedoch dazu, dass der Abruf fehlschlägt, wenn er auf einen NULL-Wert stößt und keine Möglichkeit hat, SQL_NULL_DATA zurückzugeben.

Wenn der Aufruf von SQLBindCol fehlschlägt, ist der Inhalt der Deskriptorfelder, die er in der ARD festgelegt hätte, undefiniert, und der Wert des SQL_DESC_COUNT Felds der ARD ist unverändert.

Implizites Zurücksetzen von COUNT Field

SQLBindCol legt SQL_DESC_COUNT nur dann auf den Wert des ColumnNumber-Arguments fest, wenn dadurch der Wert von SQL_DESC_COUNT erhöht würde. Wenn der Wert im TargetValuePtr-Argument ein NULL-Zeiger ist und der Wert im ColumnNumber-Argument gleich SQL_DESC_COUNT ist (d. h. beim Aufheben der Bindung der höchsten gebundenen Spalte), wird SQL_DESC_COUNT auf die Anzahl der höchsten verbleibenden gebundenen Spalte festgelegt.

Warnungen in Bezug auf SQL_DEFAULT

Zum erfolgreichen Abrufen von Spaltendaten muss die Anwendung die Länge und den Startpunkt der Daten im Anwendungspuffer ordnungsgemäß bestimmen. Wenn die Anwendung einen expliziten TargetType-Wert angibt, werden anwendungsbedingte Missverständnisse leicht erkannt. Wenn die Anwendung jedoch einen TargetType von SQL_DEFAULT angibt, kann SQLBindCol auf eine Spalte mit einem anderen Datentyp als dem von der Anwendung vorgesehenen angewendet werden, entweder durch Änderungen an den Metadaten oder durch Anwenden des Codes auf eine andere Spalte. In diesem Fall bestimmt die Anwendung möglicherweise nicht immer den Start oder die Länge der abgerufenen Spaltendaten. Dies kann zu nicht gemeldeten Datenfehlern oder Speicherverletzungen führen.

Codebeispiel

Im folgenden Beispiel führt eine Anwendung eine SELECT-Anweisung in der Tabelle Customers aus, um einen Resultset der Kunden-IDs, Namen und Telefonnummern nach Namen sortiert zurückzugeben. Anschließend wird SQLBindCol aufgerufen, um die Datenspalten an lokale Puffer zu binden. Schließlich ruft die Anwendung jede Datenzeile mit SQLFetch ab und gibt den Namen, die ID und die Telefonnummer jedes Kunden aus.

Weitere Codebeispiele finden Sie unter SQLBulkOperations-Funktion, SQLColumns-Funktion, SQLFetchScroll-Funktion und SQLSetPos-Funktion.

// SQLBindCol_ref.cpp  
// compile with: odbc32.lib  
#include <windows.h>  
#include <stdio.h>  
  
#define UNICODE  
#include <sqlext.h>  
  
#define NAME_LEN 50  
#define PHONE_LEN 60
  
void show_error() {  
   printf("error\n");  
}  
  
int main() {  
   SQLHENV henv;  
   SQLHDBC hdbc;  
   SQLHSTMT hstmt = 0;  
   SQLRETURN retcode;  
   SQLWCHAR szName[NAME_LEN], szPhone[PHONE_LEN], sCustID[NAME_LEN];  
   SQLLEN cbName = 0, cbCustID = 0, cbPhone = 0;  
  
   // Allocate environment handle  
   retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);  
  
   // Set the ODBC version environment attribute  
   if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
      retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);   
  
      // Allocate connection handle  
      if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
         retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);  
  
         // Set login timeout to 5 seconds  
         if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
            SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);  
  
            // Connect to data source  
            retcode = SQLConnect(hdbc, (SQLWCHAR*) L"NorthWind", SQL_NTS, (SQLWCHAR*) NULL, 0, NULL, 0);  
  
            // Allocate statement handle  
            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {   
               retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);   
  
               retcode = SQLExecDirect(hstmt, (SQLWCHAR *) L"SELECT CustomerID, ContactName, Phone FROM CUSTOMERS ORDER BY 2, 1, 3", SQL_NTS);  
               if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
  
                  // Bind columns 1, 2, and 3  
                  retcode = SQLBindCol(hstmt, 1, SQL_C_WCHAR, &sCustID, 100, &cbCustID);  
                  retcode = SQLBindCol(hstmt, 2, SQL_C_WCHAR, szName, NAME_LEN, &cbName);  
                  retcode = SQLBindCol(hstmt, 3, SQL_C_WCHAR, szPhone, PHONE_LEN, &cbPhone);   
  
                  // Fetch and print each row of data. On an error, display a message and exit.  
                  for (int i=0 ; ; i++) {  
                     retcode = SQLFetch(hstmt);  
                     if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO)  
                        show_error();  
                     if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)  
                     {
                        //replace wprintf with printf
                        //%S with %ls
                        //warning C4477: 'wprintf' : format string '%S' requires an argument of type 'char *'
                        //but variadic argument 2 has type 'SQLWCHAR *'
                        //wprintf(L"%d: %S %S %S\n", i + 1, sCustID, szName, szPhone);  
                        printf("%d: %ls %ls %ls\n", i + 1, sCustID, szName, szPhone);  
                    }    
                     else  
                        break;  
                  }  
               }  
  
               // Process data  
               if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {  
                  SQLCancel(hstmt);  
                  SQLFreeHandle(SQL_HANDLE_STMT, hstmt);  
               }  
  
               SQLDisconnect(hdbc);  
            }  
  
            SQLFreeHandle(SQL_HANDLE_DBC, hdbc);  
         }  
      }  
      SQLFreeHandle(SQL_HANDLE_ENV, henv);  
   }  
}  

Weitere Informationen finden Sie unter Beispiel-ODBC-Programm.

Informationen über Finden Sie unter
Zurückgeben von Informationen zu einer Spalte in einem Resultset SQLDescribeCol-Funktion
Abrufen eines Datenblocks oder Scrollen durch ein Resultset SQLFetchScroll-Funktion
Abrufen mehrerer Datenzeilen SQLFetch-Funktion
Freigeben von Spaltenpuffern für die -Anweisung SQLFreeStmt-Funktion
Abrufen eines Teils oder des Gesamten einer Datenspalte SQLGetData-Funktion
Zurückgeben der Anzahl von Resultsetspalten SQLNumResultCols-Funktion

Weitere Informationen

ODBC-API-Referenz
ODBC-Headerdateien