让我们看一个示例代码client1.c
。第一个客户端应用程序连接到数据库,然后退出。
#include <sql.h>
#include <sqlext.h>
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char * argv[] ){
SQLRETURN result;
SQLHENV henv;
SQLHDBC hdbc;
// 1.申请环境句柄
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
// 2.设置环境属性
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
// 3.申请连接句柄
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
result = SQLConnect(hdbc, // connection handle
argv[1], SQL_NTS, // data source name
argv[2], SQL_NTS, // user name
argv[3], SQL_NTS); // password
if(result==SQL_SUCCESS || result==SQL_SUCCESS_WITH_INFO){
printf("connection ok...\n");
exit(0);
}
else{
printf("connection failed...\n");
exit(1);
}
}
使用ODBC时您会注意到的第一件事是必须创建大量句柄。句柄是一种不透明的数据类型?句柄后面有一个数据结构,但您无法访问它。
使用句柄只能做三件事:创建它、销毁它以及将它传递给函数。
ODBC句柄类型
ODBC定义了四种不同类型的句柄:
SQLHENV
是一个环境句柄,它充当ODBC API的顶级句柄。您必须先创建一个环境句柄,然后才能使用ODBC执行任何其他操作。SQLHDBC
是数据库连接的句柄。连接到数据库时,会初始化SQLHDBC
句柄。拥有有效的数据库连接句柄后,您可以分配语句句柄。- 语句句柄的类型为
SQLHSTMT
。 您必须先创建语句句柄,然后才能向数据库发送命令。结果集信息通过SQLHSTMT
句柄返回。 - ODBC定义的最后一个句柄类型是
SQLHDESC
。SQLHDESC
句柄是描述符句柄。描述符句柄在编写ODBC驱动程序(而不是客户端应用程序)时使用,并且可以在复杂的错误处理代码中使用。
您在第13行创建一个环境句柄,并通过调用 SQLAllocHandle (SQL_HANDLE_ENV,...)
对其进行初始化。SQLAllocHandle()
函数有三个参数。第一个参数指定您要创建的句柄类型。第二个参数指定新句柄的父级。最后一个参数是指向要初始化的句柄的指针。表1列出了如何使用 SQLAllocHandle()
分配不同类型的句柄。请注意,环境句柄没有父级,因此您将 SQL_NULL_HANDLE
作为第二个参数传递。
表1 SQLAllocHandle() 参数
符号名称 | 新句柄的数据类型 | 家长类型 | 描述 |
---|---|---|---|
SQL_HANDLE_ENV |
SQLHENV |
没有父级 | 环境句柄 |
SQL_HANDLE_DBC |
SQLHDBC |
SQLHENV |
数据库连接句柄 |
SQL_HANDLE_STMT |
SQLHSTMT |
SQLHDBC |
语句句柄 |
SQL_HANDLE_DESC |
SQLHDESC |
SQLHDBC |
描述符句柄 |
获得初始化的环境句柄后,您需要告诉 ODBC 库您希望找到哪个版本的 ODBC。使用 SQLSetEnvAttr()
函数告诉 ODBC 您将使用 ODBC 3.x 协议进行交互。
在第 15 行,您分配一个连接句柄(SQLHDBC
)。将此函数调用与之前对SQLAllocHandle()
的调用进行比较:
SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv );
SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc );
您可以在表1中看到环境句柄没有父级。当您分配环境句柄时,您传递 SQL_NULL_HANDLE
而不是父级句柄。当您分配连接句柄时,您是在环境上下文中分配它的;您提供一个环境句柄作为 SQLAllocHandle()
的第二个参数。
此时,在示例代码中,您已经分配了一个环境句柄,声明了要使用的 ODBC 协议,并分配了一个连接句柄。您还没有连接到数据源,我们可以使用三个函数来连接到数据源:SQLConnect()
、SQLDriverConnect()
和SQLBrowseConnect()
。最简单的连接函数是SQLConnect()
。这是 SQLConnect()
的函数原型:
SQLRETURN SQLConnect( SQLHDBC ConnectionHandle,
SQLCHAR *DataSourceName,
SQLSMALLINT DataSourceLength,
SQLCHAR *UserName,
SQLSMALLINT UserNameLength,
SQLCHAR *Password,
SQLSMALLINT PasswordLength );
当您调用SQLConnect()
时,您需要提供连接句柄、数据源名称、用户名和密码。在此示例代码中,您使用命令行参数作为数据源名称、用户名和密码。请注意,您实际上并没有计算传递给SQLConnect()
的每个字符串的长度,而是传递 SQL_NTS 来告诉 ODBC 您正在发送以 NULL 结尾的字符串。
SQLConnect()
返回 SQLRETURN
值。使 ODBC 编程复杂化的原因之一是 ODBC 定义了两个不同的SUCCESS
值:SQL_SUCCESS
和SQL_SUCCESS_WITH_INFO
,并且您必须检查这两个值中的任何一个。
在示例代码中,您只需打印一条消息来告诉用户是否可以连接到所请求的数据源。在这个例子中我有点偷懒,一个行为良好的应用程序会拆除数据库连接并正确地丢弃环境和连接句柄。在这种情况下,应用程序在完成与数据库的交互后立即退出。如果您还有更多工作要做并且不再需要数据库连接,那么释放维护连接所需的资源是个好主意。
标签:HANDLE,句柄,SQLAllocHandle,odbc,SQL,服务器,ODBC,连接,客户端 From: https://www.cnblogs.com/jl1771/p/17986044