SQLBindCol, funkcja

Zgodność
Wersja wprowadzona: Zgodność ze standardami ODBC 1.0: ISO 92

Podsumowanie
SQLBindCol wiąże bufory danych aplikacji z kolumnami w zbiorze wyników.

Syntax

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

Arguments

StatementHandle
[Dane wejściowe] Uchwyt instrukcji.

ColumnNumber
[Input] Numer kolumny zestawu wyników do powiązania. Kolumny są numerowane w rosnącej kolejności kolumn, zaczynając od 0, gdzie kolumna 0 to kolumna zakładek. Jeśli zakładki nie są używane – czyli atrybut SQL_ATTR_USE_BOOKMARKS pociąg jest ustawiony na SQL_UB_OFF – numery kolumn zaczynają się od 1.

TargetType
[Input] Identyfikator typu danych C bufora *TargetValuePtr . Gdy pobiera dane ze źródła danych za pomocą SQLFetch, SQLFetchScroll, SQLBulkOperations lub SQLSetPos, sterownik konwertuje dane na ten typ; gdy wysyła dane do źródła danych za pomocą SQLBulkOperations lub SQLSetPos, sterownik konwertuje dane z tego typu. Listę ważnych typów danych i identyfikatorów typu C można znaleźć w sekcji C Typy Danych w Załączniku D: Typy Danych.

Jeśli argument TargetType jest typem danych przedziałowych, domyślna precyzja prowadząca przedziału (2) oraz domyślna precyzja sekund interwałowych (6), ustawiona odpowiednio w polach SQL_DESC_DATETIME_INTERVAL_PRECISION i SQL_DESC_PRECISION ARD, są stosowane dla danych. Jeśli argument TargetType jest SQL_C_NUMERIC, używa się domyślnej precyzji (definiowanej przez sterownik) i domyślnej skali (0), ustawionej w polach SQL_DESC_PRECISION i SQL_DESC_SCALE ARD. Jeśli domyślna precyzja lub skala nie jest odpowiednia, aplikacja powinna wyraźnie ustawić odpowiednie pole deskryptora poprzez wywołanie SQLSetDescField lub SQLSetDescRec.

Możesz także określić rozszerzony typ danych w C. Aby uzyskać więcej informacji, zobacz Typy danych C w odBC.

TargetValuePtr
[Odroczone wejście/wyjście] Wskaźnik do bufora danych, aby powiązać z kolumną. SQLFetch i SQLFetchScroll zwracają dane w tym buforze. SQLBulkOperations zwraca dane w tym buforze, gdy Operation jest SQL_FETCH_BY_BOOKMARK; pobiera dane z tego bufora, gdy Operacja jest SQL_ADD lub SQL_UPDATE_BY_BOOKMARK. SQLSetPos zwraca dane w tym buforze, gdy Operacja jest SQL_REFRESH; pobiera dane z tego bufora, gdy Operacja jest SQL_UPDATE.

Jeśli TargetValuePtr jest wskaźnikiem null, sterownik odwiązuje bufor danych dla tej kolumny. Aplikacja może odwiązać wszystkie kolumny, wywołując SQLFreeStmt z opcją SQL_UNBIND. Aplikacja może odwiązać bufor danych dla kolumny, ale nadal mieć ograniczenie bufora długości/wskaźnika dla tej kolumny, jeśli argument TargetValuePtr w wywołaniu do SQLBindCol jest wskaźnikiem null, ale argument StrLen_or_IndPtr jest wartością poprawną.

BufferLength
[Input] Długość bufora *TargetValuePtr w bajtach.

Sterownik używa BufferLength , aby uniknąć zapisu poza koniec bufora *TargetValuePtr , gdy zwraca dane o zmiennej długości, takie jak dane znakowe lub binarne. Zauważ, że sterownik liczy znak zakończenia zerowego, gdy zwraca dane znaku do *TargetValuePtr. * TargetValuePtr musi zatem zawierać miejsce na znak zakończenia zerowego, inaczej sterownik obcina dane.

Gdy sterownik zwraca dane o stałej długości, takie jak całkowita lub struktura datowa, sterownik ignoruje BufferLength i zakłada, że bufor jest wystarczająco duży, by pomieścić dane. Dlatego ważne jest, aby aplikacja przydzieliła wystarczająco duży bufor na dane o stałej długości, w przeciwnym razie sterownik zapisze się poza koniec bufora.

SQLBindCol zwraca SQLSTATE HY090 (Nieprawidłowa długość ciągu lub bufora), gdy BufferLength jest mniejsza niż 0, ale nie, gdy BufferLength wynosi 0. Jednak jeśli TargetType określa typ znaku, aplikacja nie powinna ustawiać BufferLength na 0, ponieważ sterowniki zgodne z ISO CLI zwracają SQLSTATE HY090 (Nieprawidłowy ciąg lub długość bufora).

StrLen_or_IndPtr
[Odroczone wejście/wyjście] Wskaźnik na bufor długości/wskaźnika, aby powiązać je z kolumną. SQLFetch i SQLFetchScroll zwracają wartość w tym buforze. SQLBulkOperations pobiera wartość z tego bufora, gdy Operation jest SQL_ADD, SQL_UPDATE_BY_BOOKMARK lub SQL_DELETE_BY_BOOKMARK. SQLBulkOperations zwraca wartość w tym buforze, gdy Operacja jest SQL_FETCH_BY_BOOKMARK. SQLSetPos zwraca wartość w tym buforze, gdy Operacja jest SQL_REFRESH; pobiera wartość z tego bufora, gdy Operacja jest SQL_UPDATE.

SQLFetch, SQLFetchScroll, SQLBulkOperations oraz SQLSetPos mogą zwracać następujące wartości w buforze długości/wskaźników:

  • Długość danych dostępnych do zwrotu

  • SQL_NO_TOTAL

  • SQL_NULL_DATA

Aplikacja może umieścić następujące wartości w buforze długości/wskaźników do użycia z SQLBulkOperations lub SQLSetPos:

  • Długość przesyłanych danych

  • SQL_NTS

  • SQL_NULL_DATA

  • SQL_DATA_AT_EXEC

  • Efekt SQL_LEN_DATA_AT_EXEC makro

  • SQL_COLUMN_IGNORE

Jeśli bufor wskaźnikowy i bufor długości są oddzielnymi buforami, bufor wskaźnikowy może zwracać tylko SQL_NULL_DATA, podczas gdy bufor długości może zwracać wszystkie pozostałe wartości.

Więcej informacji można znaleźć w SQLBulkOperations Function, SQLFetch Function, SQLSetPos Function oraz Using Length/Indicator Values.

Jeśli StrLen_or_IndPtr jest wskaźnikiem zerowym, nie używa się długości ani wartości wskaźnikowej. Jest to błąd podczas pobierania danych, a dane są NULL.

Zobacz ODBC 64-Bit Information, jeśli Twoja aplikacja będzie działać na 64-bitowym systemie operacyjnym.

Zwroty

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR lub SQL_INVALID_HANDLE.

Diagnostyka

Gdy SQLBindCol zwraca SQL_ERROR lub SQL_SUCCESS_WITH_INFO, można uzyskać powiązaną wartość SQLSTATE, wywołując SQLGetDiagRec z HandleType SQL_HANDLE_STMT oraz HandleStatementHandle. Poniższa tabela przedstawia wartości SQLSTATE zwykle zwracane przez SQLBindCol i wyjaśnia każdą z nich w kontekście tej funkcji; notacja "(DM)" poprzedza opisy stanów SQL zwracanych przez Menedżera Sterowników. Kod zwracany skojarzony z każdą wartością SQLSTATE jest SQL_ERROR, chyba że określono inaczej.

SQLSTATE Error Description
01000 Ostrzeżenie ogólne Komunikat informacyjny specyficzny dla sterownika. (Funkcja zwraca SQL_SUCCESS_WITH_INFO).
07006 Naruszenie atrybutu typu danych z ograniczeniami (DM) Argument ColumnNumber był 0, a argument TargetType nie był SQL_C_BOOKMARK ani SQL_C_VARBOOKMARK.
07009 Nieprawidłowy indeks deskryptorów Wartość podana dla argumentu ColumnNumber przekraczała maksymalną liczbę kolumn w zbiorze wyników.
HY000 Błąd ogólny Wystąpił błąd, dla którego nie było określonego stanu SQLSTATE i dla którego nie zdefiniowano parametru SQLSTATE specyficznego dla implementacji. Komunikat o błędzie zwrócony przez element SQLGetDiagRec w buforze *MessageText opisuje błąd i jego przyczynę.
HY001 Błąd alokacji pamięci Sterownik nie może przydzielić pamięci wymaganej do obsługi wykonywania lub ukończenia funkcji.
HY003 Nieprawidłowy typ bufora aplikacji Argument TargetType nie był ani poprawnym typem danych, ani SQL_C_DEFAULT.
HY010 Błąd sekwencji funkcji (DM) Asynchronicznie wykonywana funkcja została wywołana dla dojścia połączenia skojarzonego z instrukcją StatementHandle. Ta asynchroniczna funkcja działała nadal, gdy wywoływano SQLBindCol .

(DM) SqlExecute, SQLExecDirect lub SQLMoreResults została wywołana dla instrukcji StatementHandle i zwrócona SQL_PARAM_DATA_AVAILABLE. Ta funkcja została wywołana przed pobraniem danych dla wszystkich parametrów przesyłanych strumieniowo.

(DM) Funkcja wykonująca asynchronicznie została wywołana dla CommandHandle i nadal działała, gdy ta funkcja została wywołana.

(DM) SQLExecute, SQLExecDirect, SQLBulkOperations lub SQLSetPos został wywołany dla instrukcjiHandle i zwrócił SQL_NEED_DATA. Ta funkcja została wywołana przed wysłaniem danych dla wszystkich parametrów wykonywania danych lub kolumn.
HY013 Błąd zarządzania pamięcią Nie można przetworzyć wywołania funkcji, ponieważ nie można uzyskać dostępu do bazowych obiektów pamięci, prawdopodobnie z powodu niskich warunków pamięci.
HY090 Nieprawidłowa długość ciągu lub buforu (DM) Wartość podana dla argumentu BufferLength była mniejsza niż 0.

(DM) Kierowca był ODBC 2. x driver, argument ColumnNumber został ustawiony na 0, a wartość podania argumentu BufferLength nie była równa 4.
HY117 Połączenie jest zawieszone z powodu nieznanego stanu transakcji. Dozwolone są tylko funkcje rozłączania i tylko do odczytu. (DM) Aby uzyskać więcej informacji na temat stanu wstrzymania, zobacz SQLEndTran, funkcja.
HYC00 Opcjonalna funkcja nie zaimplementowana Sterownik lub źródło danych nie obsługuje konwersji określonej przez połączenie argumentu TargetType i specyficznego dla sterownika typu SQL odpowiadającego kolumny.

Argument ColumnNumber to 0, a sterownik nie obsługuje zakładek.

Sterownik obsługuje tylko ODBC 2. x oraz argument TargetType był jednym z następujących elementów:

SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT

oraz dowolny z typów danych przedziału C wymienionych w Typach danych C w Załączniku D: Typy Danych.

Sterownik obsługuje tylko wersje ODBC sprzed 3.50, a argument TargetType był SQL_C_GUID.
HYT01 Upłynął limit czasu połączenia Okres przekroczenia limitu czasu połączenia wygasł, zanim źródło danych odpowiedziało na żądanie. Limit czasu połączenia jest ustawiany za pomocą parametru SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Sterownik nie obsługuje tej funkcji (DM) Sterownik skojarzony z instrukcją StatementHandle nie obsługuje funkcji.

Comments

SQLBindCol służy do powiązania lub wiązania kolumn w zbiorze wyników z buforami danych oraz buforami długości/wskaźników w aplikacji. Gdy aplikacja wywołuje SQLFetch, SQLFetchScroll lub SQLSetPos w celu pobrania danych, sterownik zwraca dane dla kolumn powiązanych w określonych buforach; więcej informacji można znaleźć w SQLFetch Function. Gdy aplikacja wywołuje SQLBulkOperations , aby zaktualizować lub wstawić wiersz, lub SQLSetPos w celu aktualizacji wiersza, sterownik pobiera dane dla powiązanych kolumn z określonych buforów; więcej informacji można znaleźć w SQLBulkOperations Function lub SQLSetPos Function. Więcej informacji o oprawianiu można znaleźć w sekcji Wyniki pobierania (Podstawowe).

Zwróć uwagę, że kolumny nie muszą być powiązane, aby pobierać dane z nich. Aplikacja może także wywołać SQLGetData , aby pobierać dane z kolumn. Chociaż możliwe jest powiązanie niektórych kolumn w wierszu i wywołanie SQLGetData dla innych, podlega to pewnym ograniczeniom. Więcej informacji można znaleźć w SQLGetData.

Kolumny oprawiania, rozwiązywania i ponownego owiązywania

Kolumna może być ograniczona, odwiązana lub odbita w dowolnym momencie, nawet po pobraniu danych z zestawu wyników. Nowe przypisanie wchodzi w życie przy następnym wywołaniu funkcji używającej przypisań. Na przykład, załóżmy, że aplikacja wiąże kolumny w zbiorze wyników i wywołuje SQLFetch. Sterownik zwraca dane do buforów powiązanych. Załóżmy teraz, że aplikacja wiąże kolumny z innym zestawem buforów. Sterownik nie umieszcza danych dla właśnie pobranego wiersza w nowo powiązanych buforach. Zamiast tego czeka, aż SQLFetch zostanie ponownie wywołany, a następnie umieszcza dane dla następnego wiersza w nowo powiązanych buforach.

Note

Atrybut SQL_ATTR_USE_BOOKMARKS instrukcji powinien być zawsze ustawiony przed przypisaniem kolumny do kolumny 0. Nie jest to wymagane, ale zdecydowanie zalecane.

Wiązanie kolumn

Aby powiązać kolumnę, aplikacja wywołuje SQLBindCol i przekazuje numer kolumny, typ, adres i długość bufora danych oraz adres bufora długości/wskaźnika. Aby uzyskać informacje o tym, jak te adresy są używane, zobacz "Adresy buforowe" później w tej sekcji. Więcej informacji o bindingu kolumn można znaleźć w artykule Using SQLBindCol.

Wykorzystanie tych buforów jest odroczone; to znaczy, aplikacja wiąże je w SQLBindCol , ale sterownik uzyskuje do nich dostęp z innych funkcji – mianowicie SQLBulkOperations, SQLFetch, SQLFetchScroll lub SQLSetPos. To aplikacja odpowiada za to, aby wskaźniki określone w SQLBindCol pozostały ważne tak długo, jak wiąże się z obowiązaniem. Jeśli aplikacja pozwoli, by te wskaźniki stały się nieważne – na przykład uwalnia bufor – a następnie wywołuje funkcję, która oczekuje ich poprawności, konsekwencje są nieokreślone. Więcej informacji można znaleźć w sekcji Deferred Buffers.

Powiązanie pozostaje w mocy do momentu zastąpienia nowym przypisaniem, odblokowania kolumny lub zwolnienia instrukcji.

Kolumny rozwiązujące

Aby odwiązać pojedynczą kolumnę, aplikacja wywołuje SQLBindCol z ColumnNumber ustawionym na numer tej kolumny i TargetValuePtr na wskaźnik null. Jeśli ColumnNumber odnosi się do kolumny niepowiązanej, SQLBindCol nadal zwraca SQL_SUCCESS.

Aby odwiązać wszystkie kolumny, aplikacja wywołuje SQLFreeStmt z fOption ustawionym na SQL_UNBIND. Można to również osiągnąć, ustawiając pole SQL_DESC_COUNT ARD na zero.

Kolumny ponowne oprawiania

Aplikacja może wykonać jedną z dwóch operacji zmieniających binding:

  • Wywołaj SQLBindCol , aby określić nowe przypisanie dla kolumny, która już jest powiązana. Sterownik nadpisuje stare oprawienie nowym.

  • Określ offset do dodania adresu bufora określonego przez wywołanie wiązania z SQLBindCol. Więcej informacji można znaleźć w następnej sekcji "Binding Offsets".

Przesunięcia wiązania

Przesunięcie wiązania to wartość dodawana do adresów buforów danych oraz długości/wskaźników (zgodnie z argumentem TargetValuePtr i StrLen_or_IndPtr ) przed ich dereferencjami. Gdy używane są offsety, przypisania są "szablonem" tego, jak rozkładane są bufory aplikacji, a aplikacja może przenieść ten "szablon" do różnych obszarów pamięci, zmieniając offset. Ponieważ ten sam offset jest dodawany do każdego adresu w każdym powiązaniu, względne przesunięcia między buforami dla różnych kolumn muszą być takie same w każdym zestawie buforów. Zawsze jest to prawdą, gdy stosuje się wiązanie wierszami po rzędach; aplikacja musi starannie rozmieszczyć swoje bufory, aby było to prawdziwe przy stosowaniu oprawy kolumnowej.

Użycie przesunięcia wiązania ma praktycznie taki sam efekt jak ponowne powiązanie kolumny przez wywołanie SQLBindCol. Różnica polega na tym, że nowe wywołanie SQLBindCol określa nowe adresy dla bufora danych i bufora długości/wskaźników, podczas gdy użycie przesunięcia wiązania nie zmienia adresów, a jedynie dodaje do nich przesunięcie. Aplikacja może określić nowy offset w dowolnym momencie, a ten offset jest zawsze dodawany do pierwotnie powiązanych adresów. W szczególności, jeśli offset jest ustawiony na 0 lub jeśli atrybut instrukcji jest ustawiony na wskaźnik null, sterownik używa pierwotnie powiązanych adresów.

Aby określić przesunięcie wiązania, aplikacja ustawia atrybut SQL_ATTR_ROW_BIND_OFFSET_PTR jako adres bufora SQLINTEGER. Zanim aplikacja wywoła funkcję korzystającą z przypisań, umieszcza przesunięcie w bajtach w tym buforze. Aby określić adres bufora do użycia, sterownik dodaje offset do adresu w powiązaniu. Suma adresu i przesunięcia musi być prawidłowym adresem, ale adres, do którego dodano przesunięcie, nie musi być ważny. Więcej informacji o tym, jak są używane przesunięcia wiązań, zobacz "Adresy buforów" później w tej sekcji.

Tablice wiązające

Jeśli rozmiar wiersza (wartość atrybutu SQL_ATTR_ROW_ARRAY_SIZE) jest większy niż 1, aplikacja wiąże tablice buforów zamiast pojedynczych buforów. Więcej informacji można znaleźć w sekcji Kursory Blokujących.

Aplikacja może wiązać tablice na dwa sposoby:

  • Wiązanie tablicy z każdą kolumną. Nazywa się to wiązaniem kolumnowym , ponieważ każda struktura danych (tablica) zawiera dane dla jednej kolumny.

  • Zdefiniuj strukturę do przechowywania danych dla całego wiersza i związaj tablicę tych struktur. Nazywa się to wiązaniem wierszowym, ponieważ każda struktura danych zawiera dane dla pojedynczego wiersza.

Każda tablica buforów musi zawierać co najmniej tyle elementów, ile rozmiar zestawu wierszy.

Note

Aplikacja musi zweryfikować, że wyrównanie jest prawidłowe. Więcej informacji na temat rozważań dotyczących wyrównania można znaleźć w sekcji Alignment.

powiązanie Column-Wise

W wiązaniu kolumnowym aplikacja przypisuje oddzielne dane oraz tablice długości/wskaźników do każdej kolumny.

Aby użyć wiązania kolumnowego, aplikacja najpierw ustawia atrybut SQL_ATTR_ROW_BIND_TYPE na SQL_BIND_BY_COLUMN. (To jest domyślna opcja.) Aby każda kolumna została ograniczona, aplikacja wykonuje następujące kroki:

  1. Przydziela tablicę buforów danych.

  2. Przydziela tablicę buforów długości/wskaźników.

    Note

    Jeśli aplikacja zapisuje bezpośrednio do deskryptorów przy użyciu przypisania kolumnowego, można użyć oddzielnych tablic dla danych długości i wskaźników.

  3. Wywołuje SQLBindCol za pomocą następujących argumentów:

    • TargetType to typ pojedynczego elementu w tablicy bufora danych.

    • TargetValuePtr to adres tablicy buforów danych.

    • BufferLength to rozmiar pojedynczego elementu w tablicy bufora danych. Argument BufferLength jest ignorowany, gdy dane są dane o stałej długości.

    • StrLen_or_IndPtr to adres tablicy długości/wskaźników.

Więcej informacji o tym, jak te informacje są wykorzystywane, można znaleźć w sekcji "Adresy buforowe" później w tej sekcji. Więcej informacji o oprawianiu kolumnowym można znaleźć w Column-Wise Binding.

powiązanie Row-Wise

W wiązaniu wierszowym aplikacja definiuje strukturę zawierającą dane oraz bufory długości/wskaźników dla każdej kolumny do ograniczenia.

Aby użyć przypisywania wierszowego, aplikacja wykonuje następujące kroki:

  1. Definiuje strukturę do przechowywania pojedynczego wiersza danych (w tym zarówno danych, jak i buforów długości/wskaźników) i przydziela tablicę tych struktur.

    Note

    Jeśli aplikacja zapisuje bezpośrednio do deskryptorów podczas stosowania przypisywania wierszowego, można użyć oddzielnych pól dla długości i danych wskaźnikowych.

  2. Ustawia atrybut SQL_ATTR_ROW_BIND_TYPE jako rozmiar struktury zawierającej pojedynczy wiersz danych lub rozmiar instancji bufora, do którego kolumny wyników będą powiązane. Długość musi zawierać miejsce dla wszystkich kolumn powiązanych oraz wszelkie wypełnienia struktury lub bufora, aby mieć pewność, że gdy adres kolumny przypisanej zostanie zwiększony o określoną długość, wynik wskaże na początek tej samej kolumny w następnym wierszu. Przy użyciu operatora sizeof w ANSI C takie zachowanie jest gwarantowane.

  3. Wywołuje SQLBindCol z następującymi argumentami dla każdej kolumny, którą ma się ograniczyć:

    • TargetType to typ członka bufora danych, który ma być powiązany z kolumną.

    • TargetValuePtr to adres członka bufora danych w pierwszym elemencie tablicy.

    • BufferLength to rozmiar członka bufora danych.

    • StrLen_or_IndPtr to adres członka długości/wskaźnika, który ma być powiązany.

Więcej informacji o tym, jak te informacje są wykorzystywane, można znaleźć w sekcji "Adresy buforowe" później w tej sekcji. Więcej informacji o oprawianiu kolumnowym można znaleźć w Row-Wise Binding.

Adresy buforów

Adres bufora to rzeczywisty adres danych lub bufora długości/wskaźnika. Sterownik oblicza adres bufora tuż przed zapisem do buforów (np. podczas pobierania). Oblicza się go na podstawie następującego wzoru, który wykorzystuje adresy określone w argumentach TargetValuePtr i StrLen_or_IndPtr , przesunięcie wiązania oraz numer wiersza:

Adres + powiązanyPrzesunięcie wiązania + ((Numer wiersza - 1) x Rozmiar elementu)

gdzie zmienne formuły są zdefiniowane zgodnie z opisaniem w poniższej tabeli.

Variable Description
Adres powiązany Dla buforów danych adres podano argumentem TargetValuePtr w SQLBindCol.

Dla buforów długości/wskaźników adres podano argumentem StrLen_or_IndPtr w SQLBindCol. Więcej informacji można znaleźć w sekcji "Dodatkowe komentarze" w sekcji "Descriptors and SQLBindCol".

Jeśli adres ograniczony wynosi 0, nie zwraca się żadnej wartości danych, nawet jeśli adres obliczony przez poprzednią formułę jest różny od zera.
Przesunięcie wiązania Jeśli stosuje się przypisanie wierszowe, wartość zapisana pod adresem określonym z atrybutem SQL_ATTR_ROW_BIND_OFFSET_PTR.

Jeśli stosuje się przypisanie kolumnowe lub jeśli wartość atrybutu SQL_ATTR_ROW_BIND_OFFSET_PTR jest wskaźnikiem null, przesunięcie wiązania wynosi 0.
Numer wiersza Numer wiersza oparty na 1 w zestawie wierszy. Dla pobierania z pojedynczego wiersza, które są domyślne, jest to 1.
Rozmiar elementu Rozmiar elementu w tablicy z ograniczeniem.

Jeśli stosuje się wiązanie kolumnowe, jest to sizeof(SQLINTEGER) dla buforów długości/wskaźników. Dla buforów danych jest to wartość argumentu BufferLength w SQLBindCol , jeśli typ danych ma zmienną długość, oraz rozmiar typu danych, jeśli typ danych ma stałą długość.

Jeśli stosuje się przypisanie wierszowe, jest to wartość atrybutu SQL_ATTR_ROW_BIND_TYPE dla buforów danych oraz długości/wskaźników.

Deskryptory i SQLBindCol

Poniższe sekcje opisują, jak SQLBindCol współpracuje z deskryptorami.

Caution

Wywołanie SQLBindCol dla jednego wypowiedzenia może wpłynąć na inne. Dzieje się tak, gdy ARD powiązany ze zdaniem jest wyraźnie alokowany i jest również powiązany z innymi instrukcjami. Ponieważ SQLBindCol modyfikuje deskryptor, modyfikacje te dotyczą wszystkich instrukcji, z którymi ten deskryptor jest powiązany. Jeśli to nie jest wymagane zachowanie, aplikacja powinna oddzielić ten deskryptor od pozostałych instrukcji przed wywołaniem SQLBindCol.

Mapowania argumentów

Koncepcyjnie SQLBindCol wykonuje następujące kroki kolejno:

  1. Wywołuje SQLGetStmtAttr , aby uzyskać uchwyt ARD.

  2. Wywołuje SQLGetDescField , aby uzyskać pole SQL_DESC_COUNT tego deskryptora, a jeśli wartość w argumentze ColumnNumber przewyższa wartość SQL_DESC_COUNT, wywołuje SQLSetDescField , aby zwiększyć wartość SQL_DESC_COUNT do ColumnNumber.

  3. Wywołuje SQLSetDescField wielokrotnie, aby przypisać wartości do następujących pól ARD:

    • Ustawia SQL_DESC_TYPE i SQL_DESC_CONCISE_TYPE na wartości TargetType, z wyjątkiem tego, że jeśli TargetType jest jednym z zwięzłych identyfikatorów podtypu datetime lub interwału, ustawia SQL_DESC_TYPE odpowiednio na SQL_DATETIME lub SQL_INTERVAL; zestawia SQL_DESC_CONCISE_TYPE do zwięzłego identyfikatora; i ustawia SQL_DESC_DATETIME_INTERVAL_CODE do odpowiadającego podkodu czasu datowego lub interwałowego.

    • Ustawia jedną lub więcej SQL_DESC_LENGTH, SQL_DESC_PRECISION, SQL_DESC_SCALE i SQL_DESC_DATETIME_INTERVAL_PRECISION, zgodnie z odpowiednim dla TargetType.

    • Ustawia pole SQL_DESC_OCTET_LENGTH na wartość BufferLength.

    • Ustawia pole SQL_DESC_DATA_PTR na wartość TargetValuePtr.

    • Ustawia pole SQL_DESC_INDICATOR_PTR na wartość StrLen_or_IndPtr. (Zobacz następujący akapit.)

    • Ustawia pole SQL_DESC_OCTET_LENGTH_PTR na wartość StrLen_or_IndPtr. (Zobacz następujący akapit.)

Zmienna, do której odnosi się argument StrLen_or_IndPtr , służy zarówno do informacji o wskaźniku, jak i długości. Jeśli fetch napotka wartość zerową dla kolumny, przechowuje SQL_NULL_DATA w tej zmiennej; w przeciwnym razie przechowuje długość danych w tej zmiennej. Przekazanie wskaźnika null jako StrLen_or_IndPtr uniemożliwia operacji pobierania zwracanie długości danych, ale powoduje niepowodzenie pobierania, jeśli napotka wartość null i nie ma możliwości zwrócenia SQL_NULL_DATA.

Jeśli wywołanie do SQLBindCol się nie powiedzie, zawartość pól deskryptoru, które ustawiłoby w ARD, pozostaje niezdefiniowana, a wartość pola SQL_DESC_COUNT ARD pozostaje niezmieniona.

Niejawne resetowanie pola COUNT

SQLBindCol ustawia SQL_DESC_COUNT na wartość argumentu ColumnNumber tylko wtedy, gdy zwiększa to wartość SQL_DESC_COUNT. Jeśli wartość w argumentze TargetValuePtr jest wskaźnikiem null, a wartość w argumentze ColumnNumber jest równa SQL_DESC_COUNT (czyli przy odwiązywaniu kolumny z najwyższą granicą), to SQL_DESC_COUNT jest ustawione na liczbę najwyższej pozostałej kolumny bound.

Ostrzeżenia dotyczące SQL_DEFAULT

Aby skutecznie pobrać dane kolumnowe, aplikacja musi prawidłowo określić długość i punkt początkowy danych w buforze aplikacji. Gdy aplikacja określa wyraźny TargetType, błędne przekonania aplikacji są łatwo wykrywalne. Jednak gdy aplikacja określa TargetType SQL_DEFAULT, SQLBindCol może być zastosowany do kolumny innego typu danych niż ten, który aplikacja zamierza, zarówno poprzez zmiany metadanych, jak i przez zastosowanie kodu do innej kolumny. W takim przypadku aplikacja nie zawsze określa początek lub długość pobieranych danych kolumnowych. Może to prowadzić do niezgłaszanych błędów danych lub naruszeń pamięci.

Przykład kodu

W poniższym przykładzie aplikacja wykonuje w tabeli Klienci polecenie SELECT , aby zwrócić zestaw wyników z identyfikatorami klientów, nazwiskami i numerami telefonów, posortowanymi według nazwy. Następnie wywołuje SQLBindCol , aby powiązać kolumny danych z lokalnymi buforami. Na koniec aplikacja pobiera każdy wiersz danych za pomocą SQLFetch i drukuje imię, identyfikator oraz numer telefonu każdego klienta.

Więcej przykładów kodu można znaleźć w SQLBulkOperations Function, SQLColumns Function, SQLFetchScroll Function oraz 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);  
   }  
}  

Zobacz także Przykładowy Program ODBC.

Aby uzyskać informacje o Zobacz
Zwracanie informacji o kolumnie w zbiorze wyników SQLDescribeCol Function
Pobieranie bloku danych lub przewijanie zestawu wyników SQLFetchScroll, funkcja
Pobieranie wielu wierszy danych SQLFetch, funkcja
Zwalnianie buforów kolumnowych na wyciągu SQLFreeStmt, funkcja
Pobieranie części lub całej kolumny danych SQLGetData, funkcja
Zwracanie liczby kolumn zbioru wyników Funkcja SQLNumResultCols