Поделиться через


SQLBindCol, функция

Соответствия
Представлена версия: соответствие стандартам ODBC 1.0: ISO 92

Сводка
SQLBindCol привязывает буферы данных приложения к столбцам в результирующем наборе.

Синтаксис

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

Аргументы

ОператорHandle
[Входные данные] Дескриптор инструкции.

ColumnNumber
[Входные данные] Число столбца результирующих наборов для привязки. Столбцы нумеруются в увеличении порядка столбцов, начиная с 0, где столбец 0 является столбцом закладки. Если закладки не используются, то атрибут инструкции SQL_ATTR_USE_BOOKMARKS имеет значение SQL_UB_OFF , а число столбцов начинается с 1.

TargetType
[Входные данные] Идентификатор типа данных C буфера *TargetValuePtr . При получении данных из источника данных с помощью SQLFetch, SQLFetchScroll, SQLBulkOperations или SQLSetPos драйвер преобразует данные в этот тип; при отправке данных в источник данных с помощью SQLBulkOperations или SQLSetPos драйвер преобразует данные из этого типа. Список допустимых типов данных C и идентификаторов типов см . в разделе "Типы данных C" в приложении D: Типы данных.

Если аргумент TargetType является типом данных интервала, то для данных используются значения интервала по умолчанию ( 2) и точность интервала по умолчанию (6), заданные в полях SQL_DESC_DATETIME_INTERVAL_PRECISION и SQL_DESC_PRECISION ARD соответственно. Если аргумент TargetType SQL_C_NUMERIC, то для данных используются точность по умолчанию (определяемый драйвером) и масштаб по умолчанию (0), заданный в полях SQL_DESC_PRECISION и SQL_DESC_SCALE ARD. Если какая-либо точность или масштаб по умолчанию не подходит, приложение должно явно задать соответствующее поле дескриптора вызовом SQLSetDescField или SQLSetDescRec.

Можно также указать расширенный тип данных C. Дополнительные сведения о типах данных см. в разделе Типы данных C в ODBC.

TargetValuePtr
[Отложенные входные и выходные данные] Указатель на буфер данных для привязки к столбцу. SQLFetch и SQLFetchScroll возвращают данные в этом буфере. SQLBulkOperations возвращает данные в этом буфере, если операция SQL_FETCH_BY_BOOKMARK; она извлекает данные из этого буфера, когда операция SQL_ADD или SQL_UPDATE_BY_BOOKMARK. SQLSetPos возвращает данные в этом буфере, если операция SQL_REFRESH; она извлекает данные из этого буфера при SQL_UPDATE операции .

Если TargetValuePtr является пустым указателем , драйвер отменяет привязку буфера данных для столбца. Приложение может отменить привязку всех столбцов, вызвав SQLFreeStmt с параметром SQL_UNBIND. Приложение может отменить привязку буфера данных для столбца, но по-прежнему имеет буфер длины или индикатора, привязанный к столбцу, если аргумент TargetValuePtr в вызове SQLBindCol является пустым указателем, но аргумент StrLen_or_IndPtr является допустимым значением.

BufferLength
[Входные данные] Длина буфера *TargetValuePtr в байтах.

Драйвер использует BufferLength , чтобы избежать записи в конце буфера *TargetValuePtr при возврате данных переменной длины, таких как символьные или двоичные данные. Обратите внимание, что драйвер подсчитывает символ завершения null при возврате символьных данных в *TargetValuePtr. *TargetValuePtr должен содержать пробел для символа завершения null или драйвер усечь данные.

Когда драйвер возвращает данные фиксированной длины, например целое число или структуру дат, драйвер игнорирует BufferLength и предполагает, что буфер достаточно велик, чтобы хранить данные. Поэтому для приложения важно выделить достаточно большой буфер для данных фиксированной длины или драйвер будет записывать в конце буфера.

SQLBindCol возвращает SQLSTATE HY090 (недопустимая строка или длина буфера), если BufferLength меньше 0, но не когда BufferLength равно 0. Однако если TargetType указывает тип символа, приложение не должно задать для BufferLength значение 0, так как драйверы, совместимые с ISO CLI, возвращают SQLSTATE HY090 (недопустимая строка или длина буфера) в этом случае.

StrLen_or_IndPtr
[Отложенные входные и выходные данные] Указатель на буфер длины или индикатора для привязки к столбцу. SQLFetch и SQLFetchScroll возвращают значение в этом буфере. SQLBulkOperations получает значение из этого буфера, если операция SQL_ADD, SQL_UPDATE_BY_BOOKMARK или SQL_DELETE_BY_BOOKMARK. SQLBulkOperations возвращает значение в этом буфере при SQL_FETCH_BY_BOOKMARK операции . SQLSetPos возвращает значение в этом буфере, если операция SQL_REFRESH; получает значение из этого буфера при SQL_UPDATE операции .

SQLFetch, SQLFetchScroll, SQLBulkOperations и SQLSetPos могут возвращать следующие значения в буфере длины или индикатора:

  • Длина возвращаемых данных

  • SQL_NO_TOTAL

  • SQL_NULL_DATA

Приложение может поместить следующие значения в буфер длины или индикатора для использования с SQLBulkOperations или SQLSetPos:

  • Длина отправляемых данных

  • SQL_NTS

  • SQL_NULL_DATA

  • SQL_DATA_AT_EXEC

  • Результат макроса SQL_LEN_DATA_AT_EXEC

  • SQL_COLUMN_IGNORE

Если буфер индикатора и буфер длины являются отдельными буферами, буфер индикатора может возвращать только SQL_NULL_DATA, а буфер длины может возвращать все остальные значения.

Дополнительные сведения см. в разделе "Функция SQLBulkOperations", функция SQLFetch, функция SQLSetPos и использование значений длины и индикатора.

Если StrLen_or_IndPtr является пустым указателем, длина или значение индикатора не используется. Это ошибка при получении данных и значении NULL.

См. сведения о 64-разрядной версии ODBC, если приложение будет работать в 64-разрядной операционной системе.

Возвраты

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR или SQL_INVALID_HANDLE.

Диагностика

Когда SQLBindCol возвращает SQL_ERROR или SQL_SUCCESS_WITH_INFO, связанное значение SQLSTATE можно получить путем вызова SQLGetDiagRec с помощью HandleType SQL_HANDLE_STMT и handle of StatementHandle. В следующей таблице перечислены значения SQLSTATE, которые обычно возвращаются SQLBindCol и объясняются каждый из них в контексте этой функции. Нотация "(DM)" предшествует описаниям SQLSTATEs, возвращаемым диспетчером драйверов. Возвращаемый код, связанный с каждым значением SQLSTATE, SQL_ERROR, если не указано иное.

SQLSTATE Error Description
01000 Общее предупреждение Информационное сообщение для конкретного драйвера. (Функция возвращает SQL_SUCCESS_WITH_INFO.)
07006 Нарушение атрибута ограниченного типа данных (DM) Аргумент ColumnNumber был 0, а аргумент TargetType не был SQL_C_BOOKMARK или SQL_C_VARBOOKMARK.
07009 Недопустимый индекс дескриптора Значение, указанное для аргумента ColumnNumber , превысило максимальное количество столбцов в результирующем наборе.
HY000 Общая ошибка Произошла ошибка, для которой не было определенного SQLSTATE и для которого не было определено значение SQLSTATE для конкретной реализации. Сообщение об ошибке, возвращаемое SQLGetDiagRec в буфере *MessageText , описывает ошибку и ее причину.
HY001 Ошибка выделения памяти Драйверу не удалось выделить память, необходимую для поддержки выполнения или завершения функции.
HY003 Недопустимый тип буфера приложения Аргумент TargetType не был допустимым типом данных или SQL_C_DEFAULT.
HY010 Ошибка последовательности функций (DM) Асинхронно выполняющаяся функция была вызвана для дескриптора соединения, связанного с ОператоромHandle. Эта асинхронная функция по-прежнему выполнялась при вызове SQLBindCol .

(DM) SQLExecute, SQLExecDirect или SQLMoreResults был вызван для ОператораHandle и возвращен SQL_PARAM_DATA_AVAILABLE. Эта функция была вызвана до получения данных для всех потоковых параметров.

(DM) асинхронно выполняющаяся функция была вызвана для StatementHandle и по-прежнему выполнялась при вызове этой функции.

(DM) SQLExecute, SQLExecDirect, SQLBulkOperations или SQLSetPos были вызваны для ОператораHandle и возвращены SQL_NEED_DATA. Эта функция была вызвана до отправки данных для всех параметров выполнения или столбцов.
HY013 Ошибка управления памятью Не удалось обработать вызов функции, так как к базовым объектам памяти не удалось получить доступ, возможно, из-за низкой памяти.
HY090 Недопустимая длина строки или буфера (DM) Значение, указанное для аргумента BufferLength , было меньше 0.

(DM) Драйвер был ODBC 2.Драйвер x , аргумент ColumnNumber имеет значение 0, а значение, указанное для аргумента BufferLength , не равно 4.
HY117 Подключение приостановлено из-за неизвестного состояния транзакции. Разрешены только функции отключения и только для чтения. (DM) Дополнительные сведения о приостановленном состоянии см. в статье SQLEndTran Function.
HYC00 Необязательный компонент не реализован Драйвер или источник данных не поддерживает преобразование, указанное в сочетании аргумента TargetType и типа данных SQL для конкретного драйвера соответствующего столбца.

Аргумент ColumnNumber был 0, и драйвер не поддерживает закладки.

Драйвер поддерживает только ODBC 2.x и аргумент TargetType были одним из следующих:

SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT

и любой из типов данных C, перечисленных в типах данных C в приложении D: Типы данных.

Драйвер поддерживает только версии ODBC до версии 3.50, а аргумент TargetType был SQL_C_GUID.
HYT01 Время ожидания для подключения истекло Срок ожидания подключения истек до того, как источник данных ответил на запрос. Период времени ожидания подключения задается через SQLSetConnectAttr SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Драйвер не поддерживает эту функцию (DM) Драйвер, связанный с StatementHandle , не поддерживает функцию.

Комментарии

SQLBindCol используется для связывания столбцов в результирующем наборе с буферами данных и буферами длины или индикатора в приложении. Когда приложение вызывает SQLFetch, SQLFetchScroll или SQLSetPos для получения данных, драйвер возвращает данные для привязанных столбцов в указанных буферах; дополнительные сведения см. в разделе "Функция SQLFetch". Когда приложение вызывает SQLBulkOperations для обновления или вставки строки или SQLSetPos для обновления строки, драйвер извлекает данные для привязанных столбцов из указанных буферов; дополнительные сведения см. в разделе "Функция SQLBulkOperations" или функция SQLSetPos. Дополнительные сведения о привязке см. в разделе "Получение результатов(базовый").

Обратите внимание, что столбцы не должны быть привязаны для получения данных из них. Приложение также может вызывать SQLGetData для получения данных из столбцов. Хотя можно привязать некоторые столбцы в строке и вызвать SQLGetData для других, это может быть связано с некоторыми ограничениями. Дополнительные сведения см. в статье SQLGetData.

Привязка, отмена привязки и повторное связывание столбцов

Столбец может быть привязан, отменять или отскок в любое время, даже после получения данных из результирующий набор. Новая привязка вступает в силу при следующем вызове функции, которая использует привязки. Например, предположим, что приложение привязывает столбцы в результирующем наборе и вызывает SQLFetch. Драйвер возвращает данные в привязанных буферах. Теперь предположим, что приложение привязывает столбцы к другому набору буферов. Драйвер не помещает данные для простой строки в только что привязанные буферы. Вместо этого он ожидает повторного вызова SQLFetch, а затем помещает данные для следующей строки в вновь привязанные буферы.

Заметка

Атрибут инструкции SQL_ATTR_USE_BOOKMARKS всегда должен быть задан перед привязкой столбца к столбцу 0. Это не обязательно, но настоятельно рекомендуется.

Привязка столбцов

Чтобы привязать столбец, приложение вызывает SQLBindCol и передает номер столбца, тип, адрес и длину буфера данных, а также адрес буфера длины или индикатора. Дополнительные сведения об использовании этих адресов см. в разделе "Буферные адреса" далее в этом разделе. Дополнительные сведения о столбцах привязки см. в разделе "Использование SQLBindCol".

Использование этих буферов отложено; То есть приложение привязывает их в SQLBindCol, но драйвер обращается к ним из других функций — а именно SQLBulkOperations, SQLFetch, SQLFetchScroll или SQLSetPos. Это ответственность приложения, чтобы убедиться, что указатели, указанные в SQLBindCol , остаются действительными, пока привязка остается в силе. Если приложение позволяет этим указателям стать недействительными , например, он освобождает буфер, а затем вызывает функцию, которая ожидает, что они будут допустимыми, последствия не определены. Дополнительные сведения см. в разделе "Отложенные буферы".

Привязка остается в силе до тех пор, пока она не будет заменена новой привязкой, столбец не подключен или оператор освобождается.

Отмена привязки столбцов

Чтобы отменить привязку одного столбца, приложение вызывает SQLBindCol с ColumnNumber , для этого столбца и TargetValuePtr задано значение NULL-указателя. Если columnNumber ссылается на несвязанный столбец, SQLBindCol по-прежнему возвращает SQL_SUCCESS.

Чтобы отменить привязку всех столбцов, приложение вызывает SQLFreeStmt с параметром fOption, равным SQL_UNBIND. Это также можно сделать, установив SQL_DESC_COUNT поле ARD равным нулю.

Повторная привязка столбцов

Приложение может выполнить одно из двух операций, чтобы изменить привязку:

  • Вызовите SQLBindCol , чтобы указать новую привязку для столбца, который уже привязан. Драйвер перезаписывает старую привязку новым.

  • Укажите смещение, которое необходимо добавить в буферный адрес, который был указан вызовом привязки к SQLBindCol. Дополнительные сведения см. в следующем разделе "Смещения привязки".

Смещения привязки

Смещение привязки — это значение, которое добавляется к адресам буферов данных и длины или индикатора (как указано в аргументе TargetValuePtr и StrLen_or_IndPtr ) перед их разыменовкой. При использовании смещения привязки представляют собой "шаблон" того, как выкладываются буферы приложения, и приложение может переместить этот "шаблон" в разные области памяти, изменив смещение. Так как одно и то же смещение добавляется к каждому адресу в каждой привязке, относительные смещения между буферами для разных столбцов должны совпадать в каждом наборе буферов. Это всегда верно, если используется привязка по строкам; Приложение должно тщательно выложить свои буферы, чтобы они были верными при использовании привязки со столбцами.

Использование смещения привязки имеет в основном тот же эффект, что и повторная привязка столбца путем вызова SQLBindCol. Разница заключается в том, что новый вызов SQLBindCol задает новые адреса для буфера данных и буфера длины или индикатора, в то время как использование смещения привязки не изменяет адреса, а просто добавляет смещение к ним. Приложение может указать новое смещение всякий раз, когда он хочет, и это смещение всегда добавляется к первоначально привязанным адресам. В частности, если для смещения задано значение 0 или если атрибут инструкции имеет значение NULL, драйвер использует исходные привязанные адреса.

Чтобы указать смещение привязки, приложение задает атрибут инструкции SQL_ATTR_ROW_BIND_OFFSET_PTR адресу буфера SQLINTEGER. Прежде чем приложение вызывает функцию, использующую привязки, она помещает смещение в байтах в этот буфер. Чтобы определить адрес используемого буфера, драйвер добавляет смещение к адресу в привязке. Сумма адреса и смещения должна быть допустимым адресом, но адрес, к которому добавляется смещение, не должен быть допустимым. Дополнительные сведения об использовании смещения привязки см. в разделе "Буферные адреса" далее в этом разделе.

Привязка массивов

Если размер набора строк (значение атрибута оператора SQL_ATTR_ROW_ARRAY_SIZE) больше 1, приложение привязывает массивы буферов вместо отдельных буферов. Дополнительные сведения см. в разделе "Блокировать курсоры".

Приложение может привязать массивы двумя способами:

  • Привязка массива к каждому столбцу. Это называется привязкой со столбцами, так как каждая структура данных (массив) содержит данные для одного столбца.

  • Определите структуру для хранения данных для всей строки и привязки массива этих структур. Это называется строковой привязкой, так как каждая структура данных содержит данные для одной строки.

Каждый массив буферов должен содержать по крайней мере столько элементов, сколько размер набора строк.

Заметка

Приложение должно убедиться, что выравнивание является допустимым. Дополнительные сведения о выравнивании см. в разделе "Выравнивание".

Привязка на уровне столбца

В привязке со столбцами приложение привязывает отдельные массивы данных и индикаторов к каждому столбцу.

Чтобы использовать привязку со столбцами, приложение сначала задает атрибут инструкции SQL_ATTR_ROW_BIND_TYPE для SQL_BIND_BY_COLUMN. (Это значение по умолчанию.) Для привязки каждого столбца приложение выполняет следующие действия:

  1. Выделяет массив буфера данных.

  2. Выделяет массив буферов длины или индикатора.

    Заметка

    Если приложение записывает непосредственно в дескрипторы при использовании привязки со столбцами, отдельные массивы можно использовать для данных длины и индикатора.

  3. Вызывает SQLBindCol со следующими аргументами:

    • TargetType — это тип одного элемента в массиве буфера данных.

    • TargetValuePtr — это адрес массива буфера данных.

    • BufferLength — это размер одного элемента в массиве буфера данных. Аргумент BufferLength игнорируется, если данные являются данными фиксированной длины.

    • StrLen_or_IndPtr — это адрес массива длины или индикатора.

Дополнительные сведения об использовании этой информации см. в разделе "Буферные адреса" далее в этом разделе. Дополнительные сведения о привязке со столбцами см. в разделе "Привязка column-Wise".

Привязка на уровне строки

В привязке по строкам приложение определяет структуру, содержащую данные и буферы длины или индикатора для привязки каждого столбца.

Чтобы использовать привязку по строкам, приложение выполняет следующие действия.

  1. Определяет структуру для хранения одной строки данных (включая буферы данных и длины или индикатора) и выделяет массив этих структур.

    Заметка

    Если приложение записывает непосредственно в дескрипторы при использовании привязки по строкам, отдельные поля можно использовать для данных длины и индикатора.

  2. Задает атрибут оператора SQL_ATTR_ROW_BIND_TYPE размер структуры, содержащей одну строку данных или размер экземпляра буфера, в который будут привязаны столбцы результатов. Длина должна содержать пространство для всех привязанных столбцов, а также любое заполнение структуры или буфера, чтобы убедиться, что при добавочном адресе привязанного столбца указана указанная длина, результат будет указывать на начало одного столбца в следующей строке. При использовании оператора sizeof в ANSI C это поведение гарантируется.

  3. Вызывает SQLBindCol со следующими аргументами для привязки каждого столбца:

    • TargetType — это тип элемента буфера данных, привязанного к столбцу.

    • TargetValuePtr — это адрес элемента буфера данных в первом элементе массива.

    • BufferLength — это размер элемента буфера данных.

    • StrLen_or_IndPtr — это адрес привязанного элемента длины или индикатора.

Дополнительные сведения об использовании этой информации см. в разделе "Буферные адреса" далее в этом разделе. Дополнительные сведения о привязке со столбцами см. в разделе "Привязка Row-Wise".

Адреса буферов

Адрес буфера — это фактический адрес буфера данных или буфера индикатора длины или индикатора. Драйвер вычисляет адрес буфера непосредственно перед записью в буферы (например, во время получения). Вычисляется из следующей формулы, которая использует адреса, указанные в TargetValuePtr и аргументах StrLen_or_IndPtr , смещение привязки и номер строки:

Смещение привязки привязанных адресов + + ((номер строки — 1) x размер элемента)

где переменные формулы определены, как описано в следующей таблице.

Переменная Description
Привязанный адрес Для буферов данных адрес, указанный аргументом TargetValuePtr в SQLBindCol.

Для буферов длины или индикатора адрес, указанный с аргументом StrLen_or_IndPtr в SQLBindCol. Дополнительные сведения см. в разделе "Дополнительные комментарии" в разделе "Дескрипторы и SQLBindCol".

Если привязанный адрес равен 0, значение данных не возвращается, даже если адрес, вычисляемый предыдущей формулой, не является ненулевой.
Смещение привязки Если используется привязка по строкам, значение, хранящееся по адресу, указанному атрибутом инструкции SQL_ATTR_ROW_BIND_OFFSET_PTR.

Если используется привязка со столбцами или если значение атрибута инструкции SQL_ATTR_ROW_BIND_OFFSET_PTR является пустым указателем, смещение привязки равно 0.
Номер строки 1-е число строки в наборе строк. Для однострочных выборок, которые являются значениями по умолчанию, это значение равно 1.
Размер элемента Размер элемента в связанном массиве.

Если используется привязка со столбцами, это sizeof(SQLINTEGER) для буферов длины или индикатора. Для буферов данных это значение аргумента BufferLength в SQLBindCol , если тип данных является переменной длиной, и размер типа данных, если тип данных имеет фиксированную длину.

Если используется привязка по строкам, это значение атрибута инструкции SQL_ATTR_ROW_BIND_TYPE для буферов данных и индикаторов.

Дескрипторы и SQLBindCol

В следующих разделах описывается взаимодействие SQLBindCol с дескрипторами.

Внимание

Вызов SQLBindCol для одной инструкции может повлиять на другие инструкции. Это происходит при явном выделении ARD, связанном с инструкцией, и также связана с другими операторами. Так как SQLBindCol изменяет дескриптор, изменения применяются ко всем операторам, с которым связан дескриптор. Если это не обязательное поведение, приложение должно отсознать этот дескриптор от других инструкций перед вызовом SQLBindCol.

Сопоставления аргументов

Концептуально SQLBindCol выполняет следующие действия в последовательности:

  1. Вызывает SQLGetStmtAttr для получения дескриптора ARD.

  2. Вызывает SQLGetDescField для получения поля SQL_DESC_COUNT дескриптора, и если значение в аргументе ColumnNumber превышает значение SQL_DESC_COUNT, вызывает SQLSetDescField, чтобы увеличить значение SQL_DESC_COUNT в ColumnNumber.

  3. Вызывает SQLSetDescField несколько раз, чтобы назначить значения следующим полям ARD:

    • Задает SQL_DESC_TYPE и SQL_DESC_CONCISE_TYPE значение TargetType, за исключением того, что если TargetType является одним из кратких идентификаторов подтипа datetime или интервала, он задает SQL_DESC_TYPE SQL_DATETIME или SQL_INTERVAL соответственно; задает SQL_DESC_CONCISE_TYPE в краткий идентификатор и задает SQL_DESC_DATETIME_INTERVAL_CODE соответствующего подкода даты и интервала.

    • Задает один или несколько SQL_DESC_LENGTH, SQL_DESC_PRECISION, SQL_DESC_SCALE и SQL_DESC_DATETIME_INTERVAL_PRECISION в соответствии с TargetType.

    • Задает поле SQL_DESC_OCTET_LENGTH значение BufferLength.

    • Задает поле SQL_DESC_DATA_PTR значение TargetValuePtr.

    • Задает поле SQL_DESC_INDICATOR_PTR значением StrLen_or_IndPtr. (См. следующий абзац.)

    • Задает поле SQL_DESC_OCTET_LENGTH_PTR значением StrLen_or_IndPtr. (См. следующий абзац.)

Переменная, на которую ссылается аргумент StrLen_or_IndPtr , используется как для сведений о индикаторе, так и для длины. Если получение обнаруживает значение NULL для столбца, оно сохраняет SQL_NULL_DATA в этой переменной; в противном случае он сохраняет длину данных в этой переменной. Передача указателя null, так как StrLen_or_IndPtr сохраняет операцию получения данных от возврата длины данных, но делает получение сбоем, если он сталкивается со значением NULL и не имеет способа вернуть SQL_NULL_DATA.

Если вызов SQLBindCol завершается ошибкой, содержимое полей дескриптора, заданных в ARD, не определено, а значение поля SQL_DESC_COUNT ARD не изменяется.

Неявное сбросирование поля COUNT

SQLBindCol задает SQL_DESC_COUNT значение аргумента ColumnNumber только в том случае, если это приведет к увеличению значения SQL_DESC_COUNT. Если значение в аргументе TargetValuePtr является пустым указателем, а значение в аргументе ColumnNumber равно SQL_DESC_COUNT (то есть при отмене привязки столбца с наивысшей привязкой), то SQL_DESC_COUNT задано число самого высокого оставшегося ограничивающего столбца.

Осторожность в отношении SQL_DEFAULT

Чтобы успешно получить данные столбцов, приложение должно правильно определить длину и начальную точку данных в буфере приложения. Если приложение указывает явный TargetType, то ошибки приложений легко обнаруживаются. Однако если приложение указывает targetType SQL_DEFAULT, SQLBindCol можно применить к столбцу другого типа данных, который предназначен для приложения, либо от изменений в метаданных, либо путем применения кода к другому столбцу. В этом случае приложение может не всегда определять начальную или длину данных столбца. Это может привести к неотреченным ошибкам данных или нарушениям памяти.

Пример кода

В следующем примере приложение выполняет инструкцию SELECT в таблице Customers, чтобы вернуть результирующий набор идентификаторов клиентов, имен и номеров телефонов, отсортированных по имени. Затем он вызывает SQLBindCol , чтобы привязать столбцы данных к локальным буферам. Наконец, приложение извлекает каждую строку данных с помощью SQLFetch и выводит имя, идентификатор и номер телефона каждого клиента.

Дополнительные примеры кода см. в разделе "Функция SQLBulkOperations", функция SQLColumns, функция SQLFetchScroll и функция SQLSetPos.

// 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);  
   }  
}  

См. также пример программы ODBC.

Сведения Раздел
Возврат сведений о столбце в результирующем наборе Функция SQLDescribeCol
Получение блока данных или прокрутка результирующий набор Функция SQLFetchScroll
Получение нескольких строк данных Функция SQLFetch
Освобождение буферов столбцов в инструкции Функция SQLFreeStmt
Извлечение части или всех столбцов данных Функция SQLGetData
Возврат числа столбцов результирующего набора Функция SQLNumResultCols

См. также

Справочник по API ODBC
Файлы заголовков ODBC