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


Функция SQLAllocHandle

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

Сводка
SQLAllocHandle выделяет среду, соединение, оператор или дескриптор.

Примечание.

Эта функция является универсальной функцией для выделения дескрипторов, заменяющих функции ODBC 2.0 SQLAllocConnect, SQLAllocEnv и SQLAllocStmt. Чтобы разрешить приложениям, вызывающим SQLAllocHandle , работать с ODBC 2.Драйверы x , вызов SQLAllocHandle сопоставляется в диспетчере драйверов с SQLAllocConnect, SQLAllocEnv или SQLAllocStmt по мере необходимости. Дополнительные сведения см. в разделе "Комментарии". Дополнительные сведения о том, с чем диспетчер драйверов сопоставляет эту функцию при использовании ODBC 3.Приложение x работает с ODBC 2.Драйвер x см. в разделе "Функции замены сопоставления" для обеспечения обратной совместимости приложений.

Синтаксис

  
SQLRETURN SQLAllocHandle(  
      SQLSMALLINT   HandleType,  
      SQLHANDLE     InputHandle,  
      SQLHANDLE *   OutputHandlePtr);  

Аргументы

HandleType
[Входные данные] Тип дескриптора, выделяемого SQLAllocHandle. Необходимо установить одно из следующих значений.

  • SQL_HANDLE_DBC

  • SQL_HANDLE_DBC_INFO_TOKEN

  • SQL_HANDLE_DESC

  • SQL_HANDLE_ENV

  • SQL_HANDLE_STMT

SQL_HANDLE_DBC_INFO_TOKEN дескриптор используется только диспетчером драйверов и драйвером. Приложения не должны использовать этот тип дескриптора. Дополнительные сведения о SQL_HANDLE_DBC_INFO_TOKEN см. в статье "Разработка осведомленности о пуле подключений" в драйвере ODBC.

InputHandle
[Входные данные] Дескриптор ввода, в контексте которого будет выделен новый дескриптор. Если HandleType SQL_HANDLE_ENV, это SQL_NULL_HANDLE. Если HandleType SQL_HANDLE_DBC, это должен быть дескриптор среды, и если он SQL_HANDLE_STMT или SQL_HANDLE_DESC, он должен быть дескриптором соединения.

OutputHandlePtr
[Выходные данные] Указатель на буфер, в котором возвращается дескриптор в только что выделенную структуру данных.

Возвраты

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_INVALID_HANDLE или SQL_ERROR.

При выделении дескриптора, отличного от дескриптора среды, если SQLAllocHandleHandlePtlePtr возвращает SQL_ERROR, значение OutputHandlePtr SQL_NULL_HDBC, SQL_NULL_HSTMT или SQL_NULL_HDESC в зависимости от значения HandleType, если выходной аргумент не является пустым указателем. Затем приложение может получить дополнительные сведения из структуры диагностических данных, связанной с дескриптором в аргументе InputHandle .

Ошибки выделения среды

Выделение среды происходит как в диспетчере драйверов, так и в каждом драйвере. Ошибка, возвращаемая SQLAllocHandle с помощью HandleType SQL_HANDLE_ENV, зависит от уровня, в котором произошла ошибка.

Если диспетчер драйверов не может выделить память для *OutputHandlePtr при вызове SQLAllocHandle с вызовом HandleType SQL_HANDLE_ENV, либо приложение предоставляет пустой указатель для OutputHandlePtr, SQLAllocHandleHandle возвращает SQL_ERROR. Диспетчер драйверов задает значение *OutputHandlePtr SQL_NULL_HENV (если приложение не предоставило пустой указатель, который возвращает SQL_ERROR). Нет дескриптора, с которым необходимо связать дополнительные диагностические сведения.

Диспетчер драйверов не вызывает функцию выделения среды на уровне драйвера, пока приложение не вызывает SQLConnect, SQLBrowseConnect или SQLDriverConnect. Если ошибка возникает в функции SQLAllocHandle уровня драйвера, функция SQLConnect на уровне диспетчера драйверов, SQLBrowseConnect или SQLDriverConnect возвращает SQL_ERROR. Структура диагностических данных содержит SQLSTATE IM004 (сбой драйвера SQLAllocHandle ). Ошибка возвращается в дескриптор подключения.

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

Диагностика

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

SQLSTATE Ошибка Описание
01000 Общее предупреждение Информационное сообщение для конкретного драйвера. (Функция возвращает SQL_SUCCESS_WITH_INFO.)
08003 Подключение не открыто (DM) Аргумент HandleType был SQL_HANDLE_STMT или SQL_HANDLE_DESC, но соединение, указанное аргументом InputHandle , не было открыто. Процесс подключения должен быть успешно завершен (и подключение должно быть открыто) для драйвера, чтобы выделить инструкцию или дескриптор дескриптора.
HY000 Общая ошибка Произошла ошибка, для которой не было определенного SQLSTATE и для которого не было определено значение SQLSTATE для конкретной реализации. Сообщение об ошибке, возвращаемое SQLGetDiagRec в буфере *MessageText , описывает ошибку и ее причину.
HY001 Ошибка выделения памяти (DM) Диспетчер драйверов не смог выделить память для указанного дескриптора.

Драйверу не удалось выделить память для указанного дескриптора.
HY009 Недопустимое использование указателя NULL (DM) Аргумент OutputHandlePtr был пустым указателем.
HY010 Ошибка последовательности функций (DM) Аргумент HandleType был SQL_HANDLE_DBC, а sqlSetEnvAttr не был вызван для задания атрибута среды SQL_ODBC_VERSION.

(DM) Асинхронно выполняющаяся функция была вызвана для InputHandle и по-прежнему выполнялась при вызове функции SQLAllocHandle с параметром HandleType для SQL_HANDLE_STMT или SQL_HANDLE_DESC.
HY013 Ошибка управления памятью Аргумент HandleType был SQL_HANDLE_DBC, SQL_HANDLE_STMT или SQL_HANDLE_DESC; и вызов функции не удалось обработать, так как к базовым объектам памяти не удалось получить доступ, возможно, из-за низких условий памяти.
HY014 Ограничение на превышение количества дескрипторов Заданное драйвером ограничение количества дескрипторов, которое можно выделить для типа дескриптора, указанного аргументом HandleType , достигнуто.
HY092 Недопустимый идентификатор атрибута или параметра (DM) Аргумент HandleType не был: SQL_HANDLE_ENV, SQL_HANDLE_DBC, SQL_HANDLE_STMT или SQL_HANDLE_DESC.
HY117 Подключение приостановлено из-за неизвестного состояния транзакции. Разрешены только функции отключения и только для чтения. (DM) Дополнительные сведения о приостановленном состоянии см. в статье SQLEndTran Function.
HYC00 Необязательный компонент не реализован Аргумент HandleType был SQL_HANDLE_DESC, а драйвером был ODBC 2.x driver.
HYT01 Время ожидания для подключения истекло Срок ожидания подключения истек до того, как источник данных ответил на запрос. Период времени ожидания подключения задается через SQLSetConnectAttr SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Драйвер не поддерживает эту функцию (DM) Аргумент HandleType был SQL_HANDLE_STMT, и драйвер не был допустимым драйвером ODBC.

(DM) Аргумент HandleType был SQL_HANDLE_DESC, и драйвер не поддерживает выделение дескриптора.

Комментарии

SQLAllocHandle используется для выделения дескрипторов для сред, подключений, инструкций и дескрипторов, как описано в следующих разделах. Общие сведения об дескрипторах см. в разделе "Дескрипторы".

Несколько сред, соединений или дескрипторов инструкций могут быть выделены приложением одновременно, если драйвер поддерживает несколько выделений. В ODBC ограничение не определяется на количество дескрипторов среды, подключения, инструкции или дескриптора, которые можно выделить в любое время. Драйверы могут наложить ограничение на количество определенных типов дескрипторов, которые можно выделить одновременно; Дополнительные сведения см. в документации по драйверу.

Если приложение вызывает SQLAllocHandle с *OutputHandlePtr , установленным для среды, соединения, оператора или дескриптора, который уже существует, драйвер перезаписывает сведения, связанные с дескриптором, если приложение не использует пул соединений (см. раздел "Выделение атрибута среды для пула соединений" далее в этом разделе). Диспетчер драйверов не проверяет, используется ли дескриптор, введенный в *OutputHandlePtr, и не проверяет предыдущее содержимое дескриптора перед их перезаписью.

Примечание.

Неправильное программирование приложения ODBC для вызова SQLAllocHandle два раза с той же переменной приложения, определенной для *OutputHandlePtr без вызова SQLFreeHandle, чтобы освободить дескриптор перед перераспредещением. Перезапись дескрипторов ODBC таким образом может привести к несогласованному поведению или ошибкам со стороны драйверов ODBC.

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

SQLAllocHandle не задает атрибут среды SQL_ATTR_ODBC_VERSION при вызове для выделения дескриптора среды; атрибут среды должен быть задан приложением, или SQLSTATE HY010 (ошибка последовательности функций) будет возвращен при вызове SQLAllocHandle для выделения дескриптора соединения.

Для приложений, совместимых со стандартами, SQLAllocHandle сопоставляется с SQLAllocHandleStd во время компиляции. Разница между этими двумя функциями заключается в том, что SQLAllocHandleStd задает атрибут среды SQL_ATTR_ODBC_VERSION SQL_OV_ODBC3 при вызове с аргументом HandleType , равным SQL_HANDLE_ENV. Это делается, так как приложения, совместимые со стандартами, всегда являются ODBC 3.приложения x . Кроме того, стандарты не требуют регистрации версии приложения. Это единственное различие между этими двумя функциями; в противном случае они идентичны. SQLAllocHandleStd сопоставляется с SQLAllocHandle внутри диспетчера драйверов. Поэтому сторонние драйверы не должны реализовывать SQLAllocHandleStd.

Приложения ODBC 3.8 должны использовать:

  • SQLAllocHandle и не SQLAllocHandleStd для выделения дескриптора среды.

  • SQLSetEnvAttr , чтобы задать для атрибута среды SQL_ATTR_ODBC_VERSION значение SQL_OV_ODBC3_80.

Выделение дескриптора среды

Дескриптор среды предоставляет доступ к глобальным сведениям, таким как допустимые дескрипторы подключения и активные дескрипторы подключения. Общие сведения об дескрипторах среды см. в разделе "Дескриптор среды".

Чтобы запросить дескриптор среды, приложение вызывает SQLAllocHandle с помощью HandleType SQL_HANDLE_ENV и InputHandle SQL_NULL_HANDLE. Драйвер выделяет память для сведений о среде и передает значение связанного дескриптора обратно в аргументе *OutputHandlePtr . Приложение передает значение *OutputHandle во всех последующих вызовах, требующих аргумента дескриптора среды. Дополнительные сведения см. в разделе "Выделение дескриптора среды".

В дескрипторе среды диспетчера драйверов, если уже существует дескриптор среды драйвера, то SQLAllocHandle с обработчиком SQL_HANDLE_ENV не вызывается в этом драйвере при подключении только SQLAllocHandle с обработчиком SQL_HANDLE_DBC. Если дескриптор среды драйвера не существует в дескрипторе среды диспетчера драйверов, то при первом дескрипторе подключения среды с помощью HandleType SQL_HANDLE_ENV и SQLAllocHandle с SQL_HANDLE_DBC вызывается в драйвере, когда первый дескриптор подключения среды подключен к драйверу.

Когда диспетчер драйверов обрабатывает функцию SQLAllocHandle с помощью HandleType SQL_HANDLE_ENV, он проверяет ключевое слово Trace в разделе [ODBC] системной информации. Если для него задано значение 1, диспетчер драйверов включает трассировку для текущего приложения. Если установлен флаг трассировки, трассировка начинается при выделении первого дескриптора среды и заканчивается при освобождении последнего дескриптора среды. Дополнительные сведения см. в разделе "Настройка источников данных".

После выделения дескриптора среды приложение должно вызвать SQLSetEnvAttr в дескрипторе среды, чтобы задать атрибут среды SQL_ATTR_ODBC_VERSION. Если этот атрибут не задан перед вызовом SQLAllocHandle для выделения дескриптора подключения в среде, вызов выделения соединения вернет SQLSTATE HY010 (ошибка последовательности функций). Дополнительные сведения см. в разделе "Объявление версии ODBC приложения".

Выделение общих сред для пула подключений

Среды можно совместно использовать между несколькими компонентами в одном процессе. Общая среда может использоваться несколькими компонентами одновременно. Если компонент использует общую среду, он может использовать пуловые подключения, которые позволяют выделить и использовать существующее подключение без повторного создания этого подключения.

Перед выделением общей среды, которую можно использовать для пула подключений, приложение должно вызвать SQLSetEnvAttr , чтобы задать атрибут среды SQL_ATTR_CONNECTION_POOLING значение SQL_CP_ONE_PER_DRIVER или SQL_CP_ONE_PER_HENV. В этом случае SQLSetEnvAttr вызывается с параметром EnvironmentHandle , равным NULL, что делает атрибут атрибутом уровня процесса.

После включения пула подключений приложение вызывает SQLAllocHandle с аргументом HandleType , равным SQL_HANDLE_ENV. Среда, выделенная этим вызовом, будет неявной общей средой, так как пул подключений включен.

При выделении общей среды среда, которая будет использоваться, не определяется до вызова SQLAllocHandle с помощью HandleType SQL_HANDLE_DBC. На этом этапе диспетчер драйверов пытается найти существующую среду, соответствующую атрибутам среды, запрошенной приложением. Если такая среда отсутствует, она создается в качестве общей среды. Диспетчер драйверов поддерживает количество ссылок для каждой общей среды; Значение счетчика равно 1 при первом создании среды. Если обнаружена соответствующая среда, дескриптор этой среды возвращается приложению, а число ссылок увеличивается. Дескриптор среды, выделенный таким образом, можно использовать в любой функции ODBC, которая принимает дескриптор среды в качестве входного аргумента.

Выделение дескриптора соединения

Дескриптор подключения предоставляет доступ к таким сведениям, как допустимая инструкция и дескриптор для подключения, и открыта ли транзакция в данный момент. Общие сведения об дескрипторах подключения см. в разделе "Дескрипторы подключений".

Чтобы запросить дескриптор подключения, приложение вызывает SQLAllocHandle с помощью HandleType SQL_HANDLE_DBC. Аргумент InputHandle имеет дескриптор среды, возвращаемый вызовом SQLAllocHandle , который выделил этот дескриптор. Драйвер выделяет память для сведений о подключении и передает значение связанного дескриптора обратно в *OutputHandlePtr. Приложение передает значение *OutputHandlePtr во всех последующих вызовах, требующих дескриптора подключения. Дополнительные сведения см. в разделе "Выделение дескриптора соединения".

Диспетчер драйверов обрабатывает функцию SQLAllocHandle и вызывает функцию SQLAllocHandle драйвера, когда приложение вызывает SQLConnect, SQLBrowseConnect или SQLDriverConnect. (Дополнительные сведения см. в разделе Функция SQLConnect.)

Если атрибут среды SQL_ATTR_ODBC_VERSION не задан перед вызовом SQLAllocHandle для выделения дескриптора подключения в среде, вызов выделения подключения вернет SQLSTATE HY010 (ошибка последовательности функций).

Когда приложение вызывает SQLAllocHandle с аргументом InputHandle, равным SQL_HANDLE_DBC, а также задает дескриптор общей среды, диспетчер драйверов пытается найти существующую общую среду, которая соответствует атрибутам среды, заданным приложением. Если такая среда не существует, создается один из них с числом ссылок (поддерживается диспетчером драйверов) 1. Если найдена соответствующая общая среда, этот дескриптор возвращается приложению, а его число ссылок увеличивается.

Фактическое подключение, которое будет использоваться, не определяется диспетчером драйверов до вызова SQLConnect или SQLDriverConnect. Диспетчер драйверов использует параметры подключения в вызове SQLConnect (или ключевые слова подключения в вызове SQLDriverConnect) и атрибуты подключения, заданные после выделения подключения, чтобы определить, какое соединение в пуле следует использовать. Дополнительные сведения см. в разделе "Функция SQLConnect".

Выделение дескриптора инструкции

Дескриптор инструкции предоставляет доступ к сведениям о инструкциях, таким как сообщения об ошибках, имя курсора и сведения о состоянии обработки инструкций SQL. Общие сведения об дескрипторах инструкций см. в разделе "Дескрипторы инструкций".

Чтобы запросить дескриптор инструкций, приложение подключается к источнику данных, а затем вызывает SQLAllocHandle перед отправкой инструкций SQL. В этом вызове HandleType должно быть задано значение SQL_HANDLE_STMT и InputHandle должно быть задано для дескриптора подключения, возвращаемого вызовом SQLAllocHandle, который выделил этот дескриптор. Драйвер выделяет память для сведений инструкции, связывает дескриптор инструкции с указанным подключением и передает значение связанного дескриптора обратно в *OutputHandlePtr. Приложение передает значение *OutputHandlePtr во всех последующих вызовах, требующих дескриптора инструкции. Дополнительные сведения см. в разделе "Выделение дескриптора инструкций".

При выделении дескриптора инструкции драйвер автоматически выделяет набор из четырех дескрипторов и назначает дескрипторы для этих дескрипторов SQL_ATTR_APP_ROW_DESC, SQL_ATTR_APP_PARAM_DESC, SQL_ATTR_IMP_ROW_DESC и атрибуты инструкции SQL_ATTR_IMP_PARAM_DESC. Они называются неявно выделенными дескрипторами. Чтобы явно выделить дескриптор приложения, см. в следующем разделе "Выделение дескриптора дескриптора".

Выделение дескриптора дескриптора

Когда приложение вызывает SQLAllocHandle с помощью HandleType SQL_HANDLE_DESC, драйвер выделяет дескриптор приложения. Они называются явно выделенными дескрипторами. Приложение направляет драйвер для использования явно выделенного дескриптора приложения вместо автоматического выделенного для дескриптора данной инструкции путем вызова функции SQLSetStmtAttr с атрибутом SQL_ATTR_APP_ROW_DESC или SQL_ATTR_APP_PARAM_DESC. Дескриптор реализации не может быть выделен явным образом и не может указывать дескриптор реализации в вызове функции SQLSetStmtAttr .

Явно выделенные дескрипторы связаны с дескриптором соединения вместо дескриптора инструкции (как автоматически выделенные дескрипторы). Дескрипторы остаются выделенными, только если приложение фактически подключено к базе данных. Так как явно выделенные дескрипторы связаны с дескриптором подключения, приложение может связать явно выделенный дескриптор с несколькими операторами в соединении. С другой стороны, неявно выделенный дескриптор приложения не может быть связан с несколькими дескрипторами инструкций. (Она не может быть связана с любым дескриптором инструкции, отличной от выделенной для нее.) Явно выделенные дескрипторные дескрипторы можно освободить явным образом либо приложением, либо путем вызова SQLFreeHandle с помощью HandleType SQL_HANDLE_DESC или неявно при закрытии соединения.

Когда явно выделенный дескриптор освобождается, неявно выделенный дескриптор снова связывается с оператором. (Атрибут SQL_ATTR_APP_ROW_DESC или SQL_ATTR_APP_PARAM_DESC для этой инструкции снова устанавливается на неявно выделенный дескриптор.) Это верно для всех операторов, связанных с явно выделенным дескриптором подключения.

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

Пример кода

См. пример программы ODBC, функции SQLBrowseConnect, функции SQLConnect и функции SQLSetCursorName.

Сведения Смотрите
Выполнение инструкции SQL Функция SQLExecDirect
Выполнение подготовленной инструкции SQL Функция SQLExecute
Освобождение среды, соединения, оператора или дескриптора Функция SQLFreeHandle
Подготовка инструкции для выполнения Функция SQLPrepare
Настройка атрибута подключения Функция SQLSetConnectAttr
Задание поля дескриптора Функция SQLSetDescField
Настройка атрибута среды Функция SQLSetEnvAttr
Задание атрибута инструкции Функция SQLSetStmtAttr

См. также

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