Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Konformität
Version eingeführt: ODBC 1.0 Standards Compliance: ISO 92
Summary
SQLBindCol bindet Anwendungsdatenpuffer an Spalten im Ergebnisset.
Syntax
SQLRETURN SQLBindCol(
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLSMALLINT TargetType,
SQLPOINTER TargetValuePtr,
SQLLEN BufferLength,
SQLLEN * StrLen_or_IndPtr);
Argumente
StatementHandle
[Eingabe] Anweisungshandle.
Spaltennummer
[Eingabe] Nummer der Ergebnis-Set-Spalte, die gebunden werden soll. Spalten sind in steigender Reihenfolge nummeriert, beginnend bei 0, wobei Spalte 0 die Lesezeichenspalte ist. Wenn keine Lesezeichen verwendet werden – das heißt, das Attribut SQL_ATTR_USE_BOOKMARKS Anweisung wird auf SQL_UB_OFF gesetzt – beginnen die Spaltennummern bei 1.
Zieltyp
[Eingabe] Der Identifikator des C-Datentyps des *TargetValuePtr-Puffers . Wenn er Daten aus der Datenquelle mit SQLFetch, SQLFetchScroll, SQLBulkOperations oder SQLSetPos abruft, konvertiert der Treiber die Daten in diesen Typ; wenn er Daten mit SQLBulkOperations oder SQLSetPos an die Datenquelle sendet, konvertiert der Treiber die Daten aus diesem Typ. Eine Liste gültiger C-Datentypen und Typkennungen finden Sie im Abschnitt C-Datentypen im Anhang D: Datentypen.
Ist das TargetType-Argument ein Intervalldatentyp, werden für die Daten die Standard-Intervall-Führungsgenauigkeit (2) und die Standard-Intervallsekundengenauigkeit (6) verwendet, wie sie in den Feldern SQL_DESC_DATETIME_INTERVAL_PRECISION bzw. SQL_DESC_PRECISION des ARD festgelegt sind. Ist das TargetType-Argument SQL_C_NUMERIC, werden für die Daten die Standardgenauigkeit (treiberdefiniert) und die Standardskala (0) verwendet, wie sie in den Feldern SQL_DESC_PRECISION und SQL_DESC_SCALE des ARD festgelegt sind. Wenn eine Standardgenauigkeit oder Skalierung nicht angemessen 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
[Aufgeschobene Ein-/Ausgabe] Zeiger auf den Datenpuffer, um an die Spalte zu binden.
SQLFetch und SQLFetchScroll geben Daten in diesem Puffer zurück.
SQLBulkOperations gibt Daten in diesem Puffer zurück, wenn Operation SQL_FETCH_BY_BOOKMARK; er ruft Daten aus diesem Puffer ab, wenn der Betrieb SQL_ADD oder SQL_UPDATE_BY_BOOKMARK ist.
SQLSetPos gibt Daten in diesem Puffer zurück, wenn Operation SQL_REFRESH; er ruft Daten aus diesem Puffer ab, wenn Operation SQL_UPDATE ist.
Wenn TargetValuePtr ein Nullzeiger ist, entbindet der Treiber den Datenpuffer für die Spalte. Eine Anwendung kann alle Spalten entbinden, indem sie SQLFreeStmt mit der SQL_UNBIND-Option aufruft. Eine Anwendung kann den Datenpuffer für eine Spalte entbinden, aber dennoch eine Längen-/Indikatorpuffer-Schranke für die Spalte behalten, wenn das TargetValuePtr-Argument im Aufruf zu SQLBindCol ein Nullzeiger ist, das StrLen_or_IndPtr-Argument jedoch ein gültiger Wert ist.
BufferLength
[Eingabe] Länge des *TargetValuePtr-Puffers in Bytes.
Der Treiber verwendet BufferLength , um zu vermeiden, dass er über das Ende des *TargetValuePtr-Puffers hinaus schreibt, wenn er Daten mit variabler Länge wie Zeichen- oder Binärdaten zurückgibt. Beachten Sie, dass der Treiber das Null-Terminationszeichen zählt, wenn er Zeichendaten an *TargetValuePtr zurückgibt. * TargetValuePtr muss daher Speicherplatz für das Null-Terminationszeichen enthalten, sonst wird der Treiber die Daten abschneiden.
Wenn der Treiber Daten mit fester Länge zurückgibt, wie z. B. eine Ganzzahl oder eine Datumsstruktur, ignoriert der Treiber BufferLength und nimmt an, 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, sonst schreibt der Treiber am Ende des Puffers vorbei.
SQLBindCol gibt SQLSTATE HY090 (ungültige Zeichenketten- 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 setzen, da ISO-CLI-konforme Treiber in diesem Fall SQLSTATE HY090 (ungültige Zeichenkette oder Pufferlänge) zurückgeben.
StrLen_or_IndPtr
[Aufgeschobene Ein-/Ausgabe] Zeiger auf den Längen-/Indikatorpuffer, um an die Spalte zu binden.
SQLFetch und SQLFetchScroll geben in diesem Puffer einen Wert 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; er ruft einen Wert aus diesem Puffer ab, wenn Operation SQL_UPDATE ist.
SQLFetch, SQLFetchScroll, SQLBulkOperations und SQLSetPos können folgende Werte im Längen-/Indikatorpuffer zurückgeben:
Die Länge der verfügbaren Daten
SQL_NO_TOTAL
SQL_NULL_DATA
Die Anwendung kann folgende 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 Makro
SQL_COLUMN_IGNORE
Wenn der Indikatorpuffer und der Längenpuffer getrennte 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 Function, SQLFetch Function, SQLSetPos Function und Using Length/Indicator Values.
Ist StrLen_or_IndPtr ein Nullzeiger, wird keine Länge oder Indikatorwert verwendet. Dies ist ein Fehler beim Abrufen von Daten und die Daten sind NULL.
Siehe ODBC 64-Bit-Informationen, wenn Ihre Anwendung auf einem 64-Bit-Betriebssystem ausgeführt wird.
Rücklieferungen
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR oder SQL_INVALID_HANDLE.
Diagnostics
Wenn SQLBindCol SQL_ERROR oder SQL_SUCCESS_WITH_INFO zurückgibt, kann ein zugehöriger SQLSTATE-Wert erhalten werden, indem SQLGetDiagRec mit einem HandleType von SQL_HANDLE_STMT und einem Handle von StatementHandle aufgerufen wird. Die folgende Tabelle listet die typischerweise von SQLBindCol zurückgegebenen SQLSTATE-Werte auf und erklärt jeden einzelnen im Kontext dieser Funktion; die Notation "(DM)" geht den vom Treibermanager zurückgegebenen SQLSTATE-Beschreibungen voraus. Der rückgabecode, der jedem SQLSTATE-Wert zugeordnet ist, ist SQL_ERROR, sofern nicht anders angegeben.
| SQLSTATE | Fehler | Description |
|---|---|---|
| 01000 | Allgemeiner Warnhinweis | 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 TargetType-Argument war weder SQL_C_BOOKMARK noch SQL_C_VARBOOKMARK. |
| 07009 | Ungültiger Deskriptorindex | Der für das Argument angegebene Wert ColumnNumber überschritt die maximale Anzahl von Spalten im Ergebnisset. |
| 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 dessen Ursache. |
| HY001 | Speicherzuweisungsfehler | 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 den Verbindungshandle aufgerufen, der dem StatementHandle zugeordnet ist. Diese asynchrone Funktion lief noch, 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 ausführungsparametern oder -spalten gesendet wurden. |
| HY013 | Speicherverwaltungsfehler | Der Funktionsaufruf konnte nicht verarbeitet werden, da auf die zugrunde liegenden Speicherobjekte nicht zugegriffen werden konnte, möglicherweise aufgrund geringer Arbeitsspeicherbedingungen. |
| HY090 | Ungültige Zeichenfolgen- oder Pufferlänge | (DM) Der für das Argument BufferLength angegebene Wert war kleiner als 0. (DM) Der Fahrer war ein ODBC 2. x-Treiber wurde das ColumnNumber-Argument auf 0 gesetzt, und der für das Argument angegebene Wert BufferLength war nicht gleich 4. |
| HY117 | Die Verbindung wird aufgrund des unbekannten Transaktionsstatus angehalten. Es sind nur Trenn- und schreibgeschützte Funktionen zulässig. | (DM) Weitere Informationen zum angehaltenen Zustand finden Sie unter SQLEndTran Function. |
| HYC00 | Optionales Feature wurde nicht implementiert | Der Treiber oder die Datenquelle unterstützt nicht die durch die Kombination aus dem TargetType-Argument und dem treiberspezifischen SQL-Datentypen der entsprechenden Spalte angegebenen Konvertierung. Das Argument ColumnNumber war 0 und der Treiber unterstützt keine Lesezeichen. Der Treiber unterstützt nur ODBC 2. x und das Argument TargetType waren eines der folgenden: SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT und jeder der Intervall-C-Datentypen, die in C Data Types im Anhang D: Data Types aufgeführt sind. Der Treiber unterstützt nur ODBC-Versionen vor 3.50, und das Argument TargetType war 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 SQL_ATTR_CONNECTION_TIMEOUT festgelegt. |
| IM001 | Dieser Treiber unterstützt diese Funktion nicht. | (DM) Der dem StatementHandle zugeordnete Treiber unterstützt die Funktion nicht. |
Kommentare
SQLBindCol wird verwendet, um Spalten im Ergebnisset mit Datenpuffern und Längen-/Indikatorpuffern in der Anwendung zu verknüpfen 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; für weitere Informationen siehe SQLFetch-Funktion. Wenn die Anwendung SQLBulkOperations aufruft, um eine Zeile zu aktualisieren oder SQLSetPos einzufügen, um eine Zeile zu aktualisieren, ruft der Treiber die Daten für die gebundenen Spalten aus den angegebenen Puffern ab; für weitere Informationen siehe SQLBulkOperations Function oder SQLSetPos Function. Weitere Informationen zur Bindung finden Sie unter Retrieving Results (Basic).
Beachten Sie, dass Spalten nicht gebunden sein müssen, um Daten daraus abzurufen. Eine Anwendung kann auch SQLGetData aufrufen, um Daten aus Spalten abzurufen. Obwohl es möglich ist, einige Spalten in einer Reihe zu binden und für andere SQLGetData aufzurufen, unterliegt dies einigen Einschränkungen. Weitere Informationen finden Sie unter SQLGetData.
Binden, Entbinden und Neubinden Spalten
Eine Spalte kann jederzeit gebunden, ungebunden oder zurückgebunden sein, selbst nachdem Daten aus der Ergebnismenge abgerufen wurden. Die neue Bindung tritt beim nächsten Aufruf einer Funktion mit Bindungen in Kraft. Angenommen, eine Anwendung bindet die Spalten in einer Ergebnismenge und ruft SQLFetch auf. Der Treiber gibt die Daten in den gebundenen Puffern zurück. Angenommen, die Anwendung bindet die Spalten an einen anderen Puffersatz. Der Treiber legt die Daten für die gerade abgerufene Zeile nicht in die neu gebundenen Puffer. Stattdessen wartet es, bis SQLFetch erneut aufgerufen wird, und legt dann die Daten für die nächste Zeile in die neu gebundenen Puffer.
Note
Das Statement-Attribut SQL_ATTR_USE_BOOKMARKS sollte immer gesetzt werden, bevor eine Spalte an Spalte 0 gebunden wird. Das 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 später in diesem Abschnitt unter "Pufferadressen". Weitere Informationen zu Bindungsspalten finden Sie unter Using SQLBindCol.
Die Verwendung dieser Puffer ist aufgeschoben; das heißt, die Anwendung bindet sie in SQLBindCol , aber der Treiber greift über andere Funktionen auf sie auf – 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 in Kraft bleibt. Wenn die Anwendung zulässt, dass diese Zeiger ungültig werden – zum Beispiel wird ein Puffer freigegeben – und dann eine Funktion aufgerufen, die erwartet, dass sie gültig sind, sind die Konsequenzen undefiniert. Weitere Informationen finden Sie unter Deferred Buffers.
Die Bindung bleibt in Kraft, bis sie durch eine neue Bindung ersetzt wird, die Spalte entbindet wird oder die Aussage freigegeben wird.
Entbindende Spalten
Um eine einzelne Spalte zu entbinden, ruft eine Anwendung SQLBindCol auf, wobei ColumnNumber auf die Nummer dieser Spalte gesetzt ist und TargetValuePtr auf einen Nullzeiger gesetzt ist. Wenn sich ColumnNumber auf eine ungebundene Spalte bezieht, gibt SQLBindCol weiterhin SQL_SUCCESS zurück.
Um alle Spalten zu entbinden, ruft eine Anwendung SQLFreeStmt mit fOption auf SQL_UNBIND auf. Dies kann auch erreicht werden, indem das SQL_DESC_COUNT Feld der ARD auf null gesetzt wird.
Rebindungs-Spalten
Eine Anwendung kann eine von zwei Vorgängen ausführen, um eine Bindung zu ändern:
Rufen Sie SQLBindCol auf, um eine neue Bindung für eine bereits gebundene Spalte zu spezifizieren. Der Treiber überschreibt die alte Bindung mit dem neuen.
Geben Sie einen Offset an, der zur Pufferadresse hinzugefügt werden soll, der durch den Bindungsaufruf zu SQLBindCol angegeben wurde. Weitere Informationen finden Sie im nächsten Abschnitt "Binding Offsets".
Bindungsversätze
Ein Bindungsoffset ist ein Wert, der zu den Adressen der Daten- und Längen-/Indikatorpuffer hinzugefügt wird (wie im TargetValuePtr- und StrLen_or_IndPtr-Argument angegeben), bevor sie dereferiert werden. Wenn Offsets verwendet werden, sind die Bindungen eine "Vorlage" dafür, wie die Puffer der Anwendung angeordnet sind, und die Anwendung kann diese "Vorlage" durch Änderung des Offsets in verschiedene Speicherbereiche verschieben. Da in jeder Bindung derselbe Offset zu jeder Adresse hinzugefügt wird, müssen die relativen Versätze zwischen Puffern für verschiedene Spalten innerhalb jedes Puffersets gleich sein. Dies gilt immer, wenn reihweise Bindung verwendet wird; Die Anwendung muss ihre Puffer sorgfältig anlegen, damit dies gilt, wenn spaltenweise Bindung verwendet wird.
Die Verwendung eines Binding-Offset hat im Grunde denselben Effekt wie das Neubinden einer Spalte durch den Aufruf 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 Binding-Offs die Adressen nicht ändert, sondern nur einen Offset hinzufügt. Die Anwendung kann jederzeit einen neuen Offset festlegen, und dieser Offset wird immer zu den ursprünglich gebundenen Adressen hinzugefügt. Insbesondere verwendet der Treiber, wenn der Offset auf 0 gesetzt ist oder wenn das Anweisungsattribut auf einen Nullzeiger gesetzt wird, die ursprünglich gebundenen Adressen.
Um einen Binding-Offset zu spezifizieren, setzt die Anwendung das Attribut SQL_ATTR_ROW_BIND_OFFSET_PTR Statement auf die Adresse eines SQLINTEGER-Puffers. Bevor die Anwendung eine Funktion aufruft, die Bindings verwendet, legt sie einen Offset in Bytes in diesen Puffer ein. Um die Adresse des zu verwendenden Puffers zu bestimmen, fügt der Treiber den Offset zur Adresse in der Bindung hinzu. Die Summe aus Adresse und Offset muss eine gültige Adresse sein, aber die Adresse, zu der der Offset hinzugefügt wird, muss nicht gültig sein. Weitere Informationen zur Verwendung von Bindungsoffsets finden Sie später in diesem Abschnitt unter "Pufferadressen".
Bindungsarrays
Wenn die Zeilensatzgröße (der Wert des SQL_ATTR_ROW_ARRAY_SIZE-Anweisungsattributs) größer als 1 ist, bindet die Anwendung Arrays von Puffern statt einzelner Puffer. Weitere Informationen finden Sie unter Block Cursors.
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.
Definiere eine Struktur, die die Daten für eine ganze Zeile speichert, und binde 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 enthalten wie die Größe des Zeilensatzes.
Note
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 spaltenweise Bindung zu verwenden, setzt die Anwendung zunächst das Attribut SQL_ATTR_ROW_BIND_TYPE Statement auf SQL_BIND_BY_COLUMN. (Dies ist die Standardeinstellung.) Damit jede Spalte gebunden werden kann, führt die Anwendung die folgenden Schritte aus:
Weist ein Datenpuffer-Array zu.
Weist ein Array von Längen-/Indikatorpuffern zu.
Note
Wenn die Anwendung direkt in Deskriptoren schreibt, wenn spaltenweise Bindung verwendet wird, können separate Arrays für Längen- und Indikatordaten verwendet werden.
Ruft SQLBindCol mit folgenden Argumenten auf:
TargetType ist der Typ eines einzelnen Elements im Datenpuffer-Array.
TargetValuePtr ist die Adresse des Datenpuffer-Arrays.
BufferLength ist die Größe eines einzelnen Elements im Datenpuffer-Array. Das Argument BufferLength 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.
Für weitere Informationen darüber, wie diese Informationen verwendet werden, siehe "Pufferadressen" später in diesem Abschnitt. Weitere Informationen zur spaltenweisen Bindung finden Sie unter Column-Wise Binding.
Zeilenbezogenes Binden
Bei der zeilenweisen Bindung definiert die Anwendung eine Struktur, die Daten und Längen-/Indikatorpuffer für jede zu bindende Spalte enthält.
Um zeilenweise Bindung zu verwenden, führt die Anwendung die folgenden Schritte aus:
Definiert eine Struktur, die eine einzelne Datenzeile enthält (einschließlich sowohl Daten als auch Längen-/Indikatorpuffer) und weist ein Array dieser Strukturen zu.
Note
Wenn die Anwendung direkt in Deskriptoren schreibt, wenn zeilenweise Bindung verwendet wird, können separate Felder für Längen- und Indikatordaten verwendet werden.
Setzt das SQL_ATTR_ROW_BIND_TYPE-Statement-Attribut auf die Größe der Struktur, die eine einzelne Datenzeile enthält, oder auf die Größe einer Pufferinstanz, in die die Ergebnisspalten gebunden werden. Die Länge muss Speicherplatz für alle gebundenen Spalten und jegliches Auffüllen der Struktur oder des Puffers enthalten, um sicherzustellen, dass bei Inkrementisierung der Adresse einer gebundenen Spalte mit der angegebenen Länge das Ergebnis auf den Anfang derselben Spalte in der nächsten Zeile zeigt. Bei Verwendung des Sizeof-Operators in ANSI C ist dieses Verhalten garantiert.
Ruft SQLBindCol mit folgenden Argumenten für jede zu bindende Spalte auf:
TargetType ist der Typ des Datenpuffer-Mitglieds, das an die Spalte gebunden wird.
TargetValuePtr ist die Adresse des Datenpuffermitglieds im ersten Array-Element.
BufferLength ist die Größe des Datenpuffer-Elements.
StrLen_or_IndPtr ist die Adresse des längen-/Indikatorelements, das gebunden werden soll.
Für weitere Informationen darüber, wie diese Informationen verwendet werden, siehe "Pufferadressen" später in diesem Abschnitt. 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 kurz bevor er in die Puffer schreibt (z. B. während der Abrufzeit). Sie wird aus folgender Formel berechnet, die die in den Argumenten TargetValuePtr und StrLen_or_IndPtr angegebenen Adressen, den Bindungsoffset und die Zeilennummer verwendet:
Gebundene Adresse + Binding Offset + ((Zeilennummer - 1) x Elementgröße)
wobei die Variablen der Formel wie in der folgenden Tabelle beschrieben definiert sind.
| Variable | Description |
|---|---|
| Gebundene Adresse | Für Datenpuffer gilt die mit dem TargetValuePtr-Argument in SQLBindCol angegebene Adresse. Für Längen-/Indikatorpuffer gilt die mit dem StrLen_or_IndPtr-Argument in SQLBindCol angegebene Adresse. Weitere Informationen finden Sie unter "Zusätzliche Kommentare" im Abschnitt "Descriptors and SQLBindCol". Ist die gebundene Adresse 0, wird kein Datenwert zurückgegeben, selbst wenn die Adresse wie in der vorherigen Formel berechnet nicht null ist. |
| Bindungsoffset | Wenn zeilenweise Bindung verwendet wird, wird der Wert an der mit dem Attribut SQL_ATTR_ROW_BIND_OFFSET_PTR angegebenen Adresse gespeichert. Wenn spaltenweise Bindung verwendet wird oder der Wert des Attributs SQL_ATTR_ROW_BIND_OFFSET_PTR Statement ein Nullzeiger ist, ist der Binding Offset 0. |
| Reihennummer | Die 1-basierte Zahl der Reihe im Zeilensatz. Für Einreihe-Abrufe, die standardmäßig sind, ist dies 1. |
| Elementgröße | Die Größe eines Elements im gebundenen Array. Wenn eine spaltenweise Bindung verwendet wird, ist dies sizeof(SQLINTEGER) für Längen-/Indikatorpuffer. Für Datenpuffer ist es der Wert des BufferLength-Arguments in SQLBindCol , wenn der Datentyp eine variable Länge hat, und die Größe des Datentyps, wenn der Datentyp eine feste Länge hat. Wenn zeilenweise Bindung verwendet wird, ist dies der Wert des SQL_ATTR_ROW_BIND_TYPE-Statement-Attributs sowohl für Daten als auch für Längen-/Indikatorpuffer. |
Deskriptoren und SQLBindCol
Die folgenden Abschnitte beschreiben, wie SQLBindCol mit Deskriptoren interagiert.
Caution
Das Aufrufen von SQLBindCol für eine Anweisung kann andere Anweisungen beeinflussen. Dies geschieht, wenn die ARD, die der Erklärung zugeordnet ist, explizit zugeordnet wird und auch mit anderen Aussagen verknüpft ist. Da SQLBindCol den Deskriptor modifiziert, gelten die Änderungen für alle Anweisungen, mit denen dieser Deskriptor verknüpft ist. Wenn dies nicht das erforderliche Verhalten ist, sollte die Anwendung diesen Deskriptor vor dem Aufruf von SQLBindCol von den anderen Anweisungen trennen.
Argumentabbildungen
Konzeptionell führt SQLBindCol folgende Schritte nacheinander durch:
Ruft SQLGetStmtAttr auf, um den ARD-Handle zu erhalten.
Ruft SQLGetDescField auf, um das SQL_DESC_COUNT Feld dieses Deskriptors zu erhalten, und wenn der Wert im ColumnNumber-Argument den Wert von SQL_DESC_COUNT übersteigt, ruft SQLSetDescField auf, um den Wert von SQL_DESC_COUNT auf ColumnNumber zu erhöhen.
Aufruft SQLSetDescField mehrfach, um Werte den folgenden Feldern der ARD zuzuweisen:
Setzt SQL_DESC_TYPE und SQL_DESC_CONCISE_TYPE auf den Wert von TargetType, außer wenn TargetType einer der prägnanten Kennzeichen eines Date-Time- oder Intervall-Subtyps ist, setzt es SQL_DESC_TYPE auf SQL_DATETIME bzw. SQL_INTERVAL; setzt SQL_DESC_CONCISE_TYPE auf den prägnanten Identifikator; und setzt SQL_DESC_DATETIME_INTERVAL_CODE auf den entsprechenden Date-Time- oder Intervall-Subcode.
Setzt einen oder mehrere von SQL_DESC_LENGTH, SQL_DESC_PRECISION, SQL_DESC_SCALE und SQL_DESC_DATETIME_INTERVAL_PRECISION, entsprechend TargetType.
Legt das feld SQL_DESC_OCTET_LENGTH auf den Wert von BufferLength fest.
Setzt das SQL_DESC_DATA_PTR Feld auf den Wert von TargetValuePtr.
Setzt das SQL_DESC_INDICATOR_PTR Feld auf den Wert StrLen_or_IndPtr. (Siehe folgenden Absatz.)
Setzt das SQL_DESC_OCTET_LENGTH_PTR Feld auf den Wert StrLen_or_IndPtr. (Siehe folgenden Absatz.)
Die Variable, auf die sich das StrLen_or_IndPtr-Argument bezieht, wird sowohl für Indikator- als auch für Längeninformationen verwendet. Trifft ein Abruf auf einen Nullwert für die Spalte, speichert er SQL_NULL_DATA in dieser Variablen; ansonsten speichert sie die Datenlänge in dieser Variablen. Das Übergeben eines Nullzeigers als StrLen_or_IndPtr verhindert, dass die Abrufoperation die Datenlänge zurückgibt, aber der Abruf scheitert, wenn er auf einen Nullwert trifft und keine Möglichkeit hat, SQL_NULL_DATA zurückzugeben.
Wenn der Aufruf zu SQLBindCol fehlschlägt, sind die Inhalte der Deskriptorfelder, die im ARD gesetzt worden wären, undefiniert und der Wert des SQL_DESC_COUNT Feldes der ARD bleibt unverändert.
Implizite Zurücksetzung des COUNT-Feldes
SQLBindCol setzt SQL_DESC_COUNT nur dann auf den Wert des ColumnNumber-Arguments , wenn dies den Wert von SQL_DESC_COUNT erhöhen würde. Wenn der Wert im TargetValuePtr-Argument ein Nullzeiger ist und der Wert im ColumnNumber-Argument gleich SQL_DESC_COUNT ist (das heißt, wenn die höchste Spalte entbindet wird), dann wird SQL_DESC_COUNT auf die Zahl der höchsten verbleibenden Spalte gesetzt.
Vorsichten bezüglich SQL_DEFAULT
Um Spaltendaten erfolgreich abzurufen, muss die Anwendung die Länge und den Ausgangspunkt der Daten im Anwendungspuffer korrekt bestimmen. Wenn die Anwendung einen expliziten TargetType angibt, werden Anwendungsmissverständnisse leicht erkannt. Wenn die Anwendung jedoch einen TargetType von SQL_DEFAULT angibt, kann SQLBindCol auf eine Spalte eines anderen Datentyps angewendet werden als der von der Anwendung vorgesehene, entweder durch Änderungen an den Metadaten oder durch Anwendung des Codes auf eine andere Spalte. In diesem Fall bestimmt die Anwendung möglicherweise nicht immer den Anfang 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 Kundentabelle aus, um eine Ergebnismenge der Kunden-IDs, Namen und Telefonnummern nach Namen sortiert zurückzugeben. Anschließend ruft es SQLBindCol auf, um die Datenspalten an lokale Puffer zu binden. Abschließend ruft die Anwendung jede Datenzeile mit SQLFetch ab und druckt den Namen, die ID und die Telefonnummer jedes Kunden aus.
Weitere Codebeispiele finden Sie unter SQLBulkOperations Function, SQLColumns Function, SQLFetchScroll Function und SQLSetPos Function.
// 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);
}
}
Siehe auch Beispiel-ODBC-Programm.
Verwandte Funktionen
| Weitere Informationen zu | Siehe |
|---|---|
| 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 |
| Freigabe von Spaltenpuffern auf der Aussage | SQLFreeStmt-Funktion |
| Abrufen eines Teils oder aller Datenspalten | SQLGetData-Funktion |
| Rückgabe der Anzahl der Ergebnismengen-Spalten | SQLNumResultCols-Funktion |