Функция 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 |