SQLConnect 函数
一致性
引入的版本:ODBC 1.0 标准符合性:ISO 92
摘要
SQLConnect 建立与驱动程序和数据源的连接。 连接句柄引用与数据源连接有关的所有信息的存储,包括状态、事务状态和错误信息。
语法
SQLRETURN SQLConnect(
SQLHDBC ConnectionHandle,
SQLCHAR * ServerName,
SQLSMALLINT NameLength1,
SQLCHAR * UserName,
SQLSMALLINT NameLength2,
SQLCHAR * Authentication,
SQLSMALLINT NameLength3);
参数
ConnectionHandle
[输入] 连接句柄。
ServerName
[输入]数据源名称。 数据可能位于与程序相同的计算机上,也可以位于网络上某个位置的另一台计算机上。 有关应用程序如何选择数据源的信息,请参阅 选择数据源或驱动程序。
NameLength1
[输入]*ServerName 的长度(以字符为单位)。
UserName
[输入]用户标识符。
NameLength2
[输入]*UserName 的长度(以字符为单位)。
身份验证
[输入]身份验证字符串通常 (密码) 。
NameLength3
[输入]*身份验证 的长度(以字符为单位)。
返回
SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_ERROR、SQL_INVALID_HANDLE或SQL_STILL_EXECUTING。
诊断
当 SQLConnect 返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,可以通过使用 handleType 为 SQL_HANDLE_DBC 和 ConnectionHandle 句柄调用 SQLGetDiagRec 来获取关联的 SQLSTATE 值。 下表列出了 SQLConnect 通常返回的 SQLSTATE 值,并说明了此函数上下文中的每个值:表示法“ (DM) ”位于驱动程序管理器返回的 SQLSTATE 说明之前。 与每个 SQLSTATE 值关联的返回代码SQL_ERROR,除非另有说明。
SQLSTATE | 错误 | 说明 |
---|---|---|
01000 | 常规警告 | 特定于驱动程序的信息性消息。 (函数返回 SQL_SUCCESS_WITH_INFO.) |
01S02 | 选项值已更改 | 驱动程序不支持 SQLSetConnectAttr 中 ValuePtr 参数的指定值,并替换了类似的值。 (函数返回 SQL_SUCCESS_WITH_INFO.) |
08001 | 客户端无法建立连接 | 驱动程序无法与数据源建立连接。 |
08002 | 正在使用的连接名称 | (DM) 指定的 ConnectionHandle 已用于与数据源建立连接,并且连接仍处于打开状态或用户正在浏览连接。 |
08004 | 服务器拒绝连接 | 数据源出于实现定义的原因拒绝建立连接。 |
08S01 | 通信链接失败 | 在函数完成处理之前,驱动程序与尝试连接的数据源之间的通信链接失败。 |
28000 | 授权规范无效 | 为参数 UserName 指定的值或为参数指定的值 Authentication 违反了数据源定义的限制。 |
HY000 | 常规错误 | 发生错误,其中没有特定的 SQLSTATE,也没有定义特定于实现的 SQLSTATE。 SQLGetDiagRec 在 *MessageText 缓冲区中返回的错误消息描述了错误及其原因。 |
HY001 | 内存分配错误 | (DM) 驱动程序管理器无法分配支持执行或完成函数所需的内存。 |
HY008 | 操作已取消 | 已为 ConnectionHandle 启用异步处理。 调用了 SQLConnect 函数,在它完成执行之前,在 ConnectionHandle 上调用了 SQLCancelHandle 函数,然后在 ConnectionHandle 上再次调用 SQLConnect 函数。 或者,调用了 SQLConnect 函数,在它完成执行之前,从多线程应用程序中的不同线程在 ConnectionHandle 上调用 SQLCancelHandle。 |
HY010 | 函数序列错误 | (DM) 为 ConnectionHandle 调用的异步执行函数 (不是此函数) ,并且调用此函数时仍在执行。 |
HY013 | 内存管理错误 | 无法处理函数调用,因为无法访问基础内存对象,可能是由于内存不足。 |
HY090 | 无效的字符串或缓冲区长度 | (DM) 为参数 NameLength1、 NameLength2 或 NameLength3 指定的值小于 0,但不等于 SQL_NTS。 (DM) 为参数 NameLength1 指定的值超出了数据源名称的最大长度。 |
HYT00 | 超时时间已到 | 与数据源的连接完成之前,查询超时期限已过期。 超时期限通过 SQLSetConnectAttr 设置,SQL_ATTR_LOGIN_TIMEOUT。 |
HY114 | 驱动程序不支持连接级别异步函数执行 | (DM) 应用程序在建立连接之前对连接句柄启用了异步操作。 但是,驱动程序不支持对连接句柄执行异步操作。 |
HYT01 | 超过连接超时时间 | 在数据源响应请求之前,连接超时期限已过期。 连接超时期限通过 SQLSetConnectAttr SQL_ATTR_CONNECTION_TIMEOUT设置。 |
IM001 | 驱动程序不支持此函数 | (DM) 数据源名称指定的驱动程序不支持 函数。 |
IM002 | 找不到数据源且未指定默认驱动程序 | (DM) 系统信息中找不到参数 ServerName 中指定的数据源名称,也没有默认驱动程序规范。 |
IM003 | 无法将指定的驱动程序连接到 | (DM) 系统信息中的数据源规范中列出的驱动程序找不到或由于某种其他原因无法连接到 。 |
IM004 | SQL_HANDLE_ENV上的驱动程序 SQLAllocHandle 失败 | (DM) SQLConnect 期间,驱动程序管理器调用了驱动程序的 SQLAllocHandle 函数, handleType 为 SQL_HANDLE_ENV,驱动程序返回错误。 |
IM005 | SQL_HANDLE_DBC上的驱动程序 SQLAllocHandle 失败 | (DM) SQLConnect 期间,驱动程序管理器调用了驱动程序的 SQLAllocHandle 函数, handleType 为 SQL_HANDLE_DBC,驱动程序返回错误。 |
IM006 | 驱动程序的 SQLSetConnectAttr 失败 | 在 SQLConnect 期间,驱动程序管理器调用了驱动程序的 SQLSetConnectAttr 函数,驱动程序返回了错误。 (函数返回 SQL_SUCCESS_WITH_INFO.) |
IM009 | 无法连接到翻译 DLL | 驱动程序无法连接到为数据源指定的转换 DLL。 |
IM010 | 数据源名称太长 | (DM) *ServerName 的长度超过 SQL_MAX_DSN_LENGTH 个字符。 |
IM014 | 指定的 DSN 包含驱动程序和应用程序之间的体系结构不匹配 | (DM) 32 位应用程序使用连接到 64 位驱动程序的 DSN;反之亦然。 |
IM015 | SQL_HANDLE_DBC_INFO_HANDLE上的驱动程序 SQLConnect 失败 | 如果驱动程序返回SQL_ERROR,驱动程序管理器将向应用程序返回SQL_ERROR,连接将失败。 有关SQL_HANDLE_DBC_INFO_TOKEN的详细信息,请参阅 在 ODBC 驱动程序中开发Connection-Pool感知。 |
IM017 | 在异步通知模式下禁用轮询 | 每当使用通知模型时,将禁用轮询。 |
IM018 | 尚未调用 SQLCompleteAsync 来完成此句柄上的上一个异步操作。 | 如果对句柄的上一个函数调用返回SQL_STILL_EXECUTING并且启用了通知模式,则必须在句柄上调用 SQLCompleteAsync 以执行后期处理并完成操作。 |
S1118 | 驱动程序不支持异步通知 | 如果驱动程序不支持异步通知,则无法设置SQL_ATTR_ASYNC_DBC_EVENT或SQL_ATTR_ASYNC_DBC_RETCODE_PTR。 |
注释
有关应用程序为何使用 SQLConnect 的信息,请参阅 使用 SQLConnect 进行连接。
在应用程序调用函数 (SQLConnect、SQLDriverConnect 或 SQLBrowseConnect) 连接到驱动程序之前,驱动程序管理器不会连接到驱动程序。 在此之前,驱动程序管理器使用自己的句柄并管理连接信息。 当应用程序调用连接函数时,驱动程序管理器会检查驱动程序当前是否为指定的 ConnectionHandle 连接到:
如果驱动程序未连接到,驱动程序管理器将连接到驱动程序,并使用 handleType SQL_HANDLE_ENV 调用 SQLAllocHandle,SQLAllocHandle 的 HandleType 为 SQL_HANDLE_DBC,SQLSetConnectAttr (如果应用程序指定了任何连接属性) ,则驱动程序中的连接函数。 驱动程序管理器返回 SQLSTATE IM006 (驱动程序的 SQLSetConnectOption 失败) ,如果驱动程序返回 SQLSetConnectAttr 错误,则SQL_SUCCESS_WITH_INFO连接函数。 有关详细信息,请参阅 连接到数据源或驱动程序。
如果指定的驱动程序已在 ConnectionHandle 上连接到,驱动程序管理器仅调用驱动程序中的连接函数。 在这种情况下,驱动程序必须确保 ConnectionHandle 的所有连接属性都保持其当前设置。
如果连接到其他驱动程序,驱动程序管理器使用 handleType SQL_HANDLE_DBC 调用 SQLFreeHandle,然后,如果该环境中没有其他驱动程序连接到,它将调用 SQLFreeHandle,并在连接的驱动程序中具有 handleType SQL_HANDLE_ENV,然后断开该驱动程序的连接。 然后,它会执行与驱动程序未连接到时相同的操作。
然后,驱动程序分配句柄并初始化自身。
当应用程序调用 SQLDisconnect 时,驱动程序管理器在驱动程序中调用 SQLDisconnect 。 但是,它不会断开驱动程序的连接。 这会将驱动程序保留在内存中,以便重复连接到数据源和从数据源断开连接的应用程序。 当应用程序调用 HandleType 为 SQL_HANDLE_DBC 的 SQLFreeHandle 时,驱动程序管理器调用 handleType 为 SQL_HANDLE_DBC 的 SQLFreeHandle,在驱动程序中调用 HandleType 为 SQL_HANDLE_ENV 的 SQLFreeHandle,然后断开驱动程序的连接。
ODBC 应用程序可以建立多个连接。
驱动程序管理器指南
*ServerName 的内容会影响驱动程序管理器和驱动程序如何协同工作以建立与数据源的连接。
如果 *ServerName 包含有效的数据源名称,驱动程序管理器在系统信息中找到相应的数据源规范,并连接到关联的驱动程序。 驱动程序管理器将每个 SQLConnect 参数传递给驱动程序。
如果找不到数据源名称或 ServerName 为 null 指针,驱动程序管理器将查找默认数据源规范并连接到关联的驱动程序。 驱动程序管理器将 UserName 和 Authentication 参数未修改传递给驱动程序,并将 ServerName 参数的“DEFAULT”传递给驱动程序。
如果 ServerName 参数为“DEFAULT”,驱动程序管理器将查找默认数据源规范并连接到关联的驱动程序。 驱动程序管理器将每个 SQLConnect 参数传递给驱动程序。
如果找不到数据源名称或 ServerName 为空指针,并且不存在默认数据源规范,驱动程序管理器将返回SQL_ERROR,SQLSTATE IM002 (找不到数据源名称,并且未) 指定默认驱动程序。
驱动程序管理器连接到驱动程序后,驱动程序可以在系统信息中找到其相应的数据源规范,并使用规范中的特定于驱动程序的信息来完成其所需的连接信息集。
如果在数据源的系统信息中指定了默认转换库,驱动程序将连接到该库。 可以通过使用 SQL_ATTR_TRANSLATE_LIB 属性调用 SQLSetConnectAttr 来连接到不同的翻译库。 可以通过使用 SQL_ATTR_TRANSLATE_OPTION 属性调用 SQLSetConnectAttr 来指定转换选项。
如果驱动程序支持 SQLConnect,则驱动程序的系统信息的驱动程序关键字部分必须包含 ConnectFunctions 关键字,第一个字符设置为“Y”。
连接池
连接池允许应用程序重复使用已创建的连接。 启用连接池并调用 SQLConnect 时,驱动程序管理器会尝试使用已指定用于连接池的环境中的连接池中的连接进行连接。 此环境是一个共享环境,由使用池中连接的所有应用程序使用。
在分配环境之前启用连接池,方法是调用 SQLSetEnvAttr 将SQL_ATTR_CONNECTION_POOLING设置为 SQL_CP_ONE_PER_DRIVER (,指定每个驱动程序) 最多一个池,或SQL_CP_ONE_PER_HENV (指定每个环境) 最多一个池。 在本例中,调用 SQLSetEnvAttr 时,EnvironmentHandle 设置为 null,这使该属性成为进程级属性。 如果SQL_ATTR_CONNECTION_POOLING设置为“SQL_CP_OFF”,则禁用连接池。
启用连接池后,将调用 handleType 为 SQL_HANDLE_ENV 的 SQLAllocHandle 来分配环境。 此调用分配的环境是共享环境,因为已启用连接池。 但是,在调用 handleType 为 SQL_HANDLE_DBC 的 SQLAllocHandle 之前,不会确定将使用的环境。
调用 handleType 为 SQL_HANDLE_DBC 的 SQLAllocHandle 来分配连接。 驱动程序管理器尝试查找与应用程序设置的环境属性匹配的现有共享环境。 如果不存在此类环境,则会创建一个作为隐式 共享环境。 如果找到匹配的共享环境,则环境句柄将返回到应用程序,并且其引用计数递增。
但是,在调用 SQLConnect 之前,不会确定将使用的连接。 此时,驱动程序管理器会尝试在连接池中找到与应用程序请求的条件匹配的现有连接。 这些条件包括调用 SQLConnect 时请求的连接选项, (ServerName、UserName 和 Authentication 关键字的值) ,以及自调用 handleType 为 SQL_HANDLE_DBC 的 SQLAllocHandle 以来设置的任何连接属性。 驱动程序管理器根据池中连接中的相应连接关键字和属性检查这些条件。 如果找到匹配项,则使用池中的连接。 如果未找到匹配项,则会创建一个新连接。
如果 SQL_ATTR_CP_MATCH 环境属性设置为 SQL_CP_STRICT_MATCH,则要使用的池中的连接必须完全匹配。 如果 SQL_ATTR_CP_MATCH 环境属性设置为 SQL_CP_RELAXED_MATCH,则对 SQLConnect 的调用中的连接选项必须匹配,但并非所有连接属性都必须匹配。
当调用 SQLConnect 之前由应用程序设置的连接属性与池中连接的连接属性不匹配时,将应用以下规则:
如果在建立连接之前必须设置连接属性:
如果SQL_CP_STRICT_MATCH SQL_ATTR_CP_MATCH,则共用连接中的SQL_ATTR_PACKET_SIZE必须与应用程序设置的属性相同。 如果SQL_CP_RELAXED_MATCH,SQL_ATTR_PACKET_SIZE的值可能不同。
SQL_ATTR_LOGIN_VALUE的值不会影响匹配。
如果在建立连接之前或之后可以设置连接属性:
如果连接属性尚未由应用程序设置,但已在池中的连接上设置,并且存在默认值,则共用连接中的连接属性将设置为默认值,并声明匹配项。 如果没有默认值,则不会将共用连接视为匹配项。
如果连接属性已由应用程序设置,但尚未在池中的连接上设置,则池中的连接属性将更改为应用程序设置的连接属性,并声明匹配项。
如果连接属性已由应用程序设置,并且已在池中的连接上设置,但值不同,则使用应用程序的连接属性的值并声明匹配项。
如果特定于驱动程序的连接属性的值不同,并且 SQL_ATTR_CP_MATCH 设置为 SQL_CP_STRICT_MATCH,则不使用池中的连接。
当应用程序调用 SQLDisconnect 断开连接时,连接将返回到连接池并可供重复使用。
优化连接池性能
当涉及分布式事务时,可以使用 SQLUINTEGER 位掩码 SQL_DTC_TRANSITION_COST优化连接池性能。 所引用的转换是连接属性SQL_ATTR_ENLIST_IN_DTC从值 0 到非零值的转换,反之亦然。 这是从未登记到分布式事务中的连接,在分布式事务中登记,反之亦然。 根据驱动程序如何实现登记 (设置连接属性SQL_ATTR_ENLIST_IN_DTC) ,这些转换可能很昂贵,因此应避免实现最佳性能。
驱动程序返回的值包含以下位的任意组合:
SQL_DTC_ENLIST_EXPENSIVE,如果设置,则意味着从零到非零值的转换比从非零值到另一个非零值的转换开销要高得多, (在其下一个事务) 登记以前登记的连接。
SQL_DTC_UNENLIST_EXPENSIVE,如果设置,则意味着非零到零的转换比使用SQL_ATTR_ENLIST_IN_DTC属性已设置为零的连接要昂贵得多。
性能与连接使用情况存在权衡。 如果驱动程序指示其中一个或多个转换成本高昂,驱动程序管理器的连接池程序将通过在池中保留更多连接来对此做出响应。 池中的某些连接优先用于非事务性使用,而有些连接则优先用于事务性使用。 但是,如果驱动程序指示这些转换不昂贵,则可以使用更少的连接,可能交替使用非事务性与事务性使用。
不支持SQL_ATTR_ENLIST_IN_DTC的驱动程序不需要支持SQL_DTC_TRANSITION_COST。 对于支持 SQL_ATTR_ENLIST_IN_DTC 但不SQL_DTC_TRANSITION_COST的驱动程序,假定转换成本不高,就好像驱动程序返回了 0 (没有为此值设置) 位一样。
虽然 odbc 3.5 中引入了 SQL_DTC_TRANSITION_COST,但 ODBC 2 中引入了 。x 驱动程序也可以支持它,因为驱动程序管理器将查询此信息,而不考虑驱动程序版本。
代码示例
在以下示例中,应用程序分配环境和连接句柄。 然后,它使用用户 ID JohnS 和密码 Sesame 连接到 SalesOrders 数据源,并处理数据。 处理完数据后,它会断开与数据源的连接,并释放句柄。
// SQLConnect_ref.cpp
// compile with: odbc32.lib
#include <windows.h>
#include <sqlext.h>
int main() {
SQLHENV henv;
SQLHDBC hdbc;
SQLHSTMT hstmt;
SQLRETURN retcode;
SQLCHAR * OutConnStr = (SQLCHAR * )malloc(255);
SQLSMALLINT * OutConnStrLen = (SQLSMALLINT *)malloc(255);
// 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, (void*)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, (SQLCHAR*) "NorthWind", SQL_NTS, (SQLCHAR*) NULL, 0, NULL, 0);
// Allocate statement handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
// Process data
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
}
SQLDisconnect(hdbc);
}
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
}
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
}
相关函数
有关以下方面的信息 | 请参阅 |
---|---|
分配句柄 | SQLAllocHandle 函数 |
发现和枚举连接到数据源所需的值 | SQLBrowseConnect 函数 |
断开与数据源的连接 | SQLDisconnect 函数 |
使用连接字符串或对话框连接到数据源 | SQLDriverConnect 函数 |
返回连接属性的设置 | SQLGetConnectAttr 函数 |
设置连接属性 | SQLSetConnectAttr 函数 |