unixODBC編程(二)連接數據庫
訪問www.tomcoding.com網站,學習Oracle內部數據結構,詳細文檔說明,下載Oracle的exp/imp,DUL,logminer,ASM工具的源代碼,學習高技術含量的內容。
ODBC函數是一些定義好的接口,有唯一的名稱,所以能夠在不同的數據庫直接移植。ODBC應用程序通過數據源名稱來找到數據源的配置信息,包括連接數據庫的必要信息和數據庫訪問的驅動程序,不同的數據庫驅動程序實現了ODBC的接口函數,因此我們能通過ODBC函數訪問數據庫。
訪問數據庫的第一步就是連接到數據庫,ODBC連接到數據庫有幾個步驟如下。
1. 創建環境句柄,在3.0版本后所以句柄的分配都用SQLAllocHandle()函數,句柄類型為SQL_HANDLE_ENV。
2. 在環境句柄中設置使用的ODBC版本,使用SQLSetEnvAttr()函數。
3. 分配連接句柄,使用SQLAllocHandle()函數,句柄類型為SQL_HANDLE_DBC。
4. 設置連接數據庫的超時時間,使用SQLSetConnectAttr()函數。
5. 連接數據庫,使用SQLConnect()函數。
下面看看這些函數的原型和參數。
分配句柄函數。
SQLRETURN SQLAllocHandle(
SQLSMALLINT HandleType,
SQLHANDLE InputHandle,
SQLHANDLE * OutputHandlePtr);
先看返回值,是一個SQLRETURN類型的值,這是一個short類型的整數,所有ODBC的函數返回值都是這個類型。返回值有下面這些SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_INVALID_HANDLE或SQL_ERROR。
再看一下參數。
HandleType是一個輸入參數,分配的句柄的類型。 必須是以下值之一:
SQL_HANDLE_DBC
SQL_HANDLE_DBC_INFO_TOKEN
SQL_HANDLE_DESC
SQL_HANDLE_ENV
SQL_HANDLE_STMT
InputHandle是一個輸入參數,是為其上下文分配新句柄的輸入句柄。 如果 handleType 為 SQL_HANDLE_ENV,則SQL_NULL_HANDLE。如果 HandleType 為 SQL_HANDLE_DBC,則必須是環境句柄,如果它是SQL_HANDLE_STMT或SQL_HANDLE_DESC,則必須是連接句柄。
OutputHandlePtr是一個輸出參數,是一個指向緩沖區的指針,該緩沖區將句柄返回到新分配的數據結構。
設置環境句柄的ODBC版本函數。
SQLRETURN SQLSetEnvAttr(
SQLHENV EnvironmentHandle,
SQLINTEGER Attribute,
SQLPOINTER ValuePtr,
SQLINTEGER StringLength);
EnvironmentHandle是一個輸入參數,環境句柄。
Attribute是一個輸入參數,要設置的屬性,在這里是SQL_ATTR_ODBC_VERSION。
ValuePtr是一個輸入參數,指向要與 Attribute 關聯的值的指針。這里是一個32位整數值。
StringLength是一個輸入參數,如果 ValuePtr 指向字符串,則此參數應為 *ValuePtr 的長度。不是字符串則忽略。
設置連接超時函數。
SQLRETURN SQLSetConnectAttr(
SQLHDBC ConnectionHandle,
SQLINTEGER Attribute,
SQLPOINTER ValuePtr,
SQLINTEGER StringLength);
與設置環境句柄的屬性函數差不多,只不過換成了連接句柄。
ConnectionHandle是一個輸入參數,連接句柄。
Attribute是一個輸入參數,要設置的屬性,這里是SQL_ATTR_LOGIN_TIMEOUT。
ValuePtr是一個輸入參數,指向要與 Attribute 關聯的值的指針。這里是一個無符號整數值,表示超時時間,以秒為單位。
StringLength是一個輸入參數,如果 Attribute 定義的屬性是一個字符串,表示字符串長度,否則忽略。
連接數據庫函數。
SQLRETURN SQLConnect(
SQLHDBC ConnectionHandle,
SQLCHAR * ServerName,
SQLSMALLINT NameLength1,
SQLCHAR * UserName,
SQLSMALLINT NameLength2,
SQLCHAR * Authentication,
SQLSMALLINT NameLength3);
ConnectionHandle是一個輸入參數,連接句柄。
ServerName是一個輸入參數,數據源名稱,在odbc.ini中配置的數據源。
NameLength1是一個輸入參數,ServerName 的長度(以字符為單位)。
UserName是一個輸入參數,用戶標識符,連接數據庫的用戶名稱。
NameLength2是一個輸入參數,UserName 的長度(以字符為單位)。
Authentication是一個輸入參數,身份驗證字符串,通常是連接數據庫用戶的密碼。
NameLength3是一個輸入參數,身份驗證Authentication的長度(以字符為單位)。
看一段連接數據庫的實際例子代碼。
#include "stdio.h" #include "stdlib.h" #include "sql.h" /* 必須包含下面的三個頭文件 */ #include "sqlext.h" #include "sqltypes.h" SQLHANDLE envh; /* environment handle */ SQLHANDLE dbch; /* connect handle */ int connect_database(char *dsn_str, char *username, char *passwd){ SQLRETURN rc; /* 分配環境句柄 */ rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &envh); if (rc != SQL_SUCCESS) { fprintf(stderr, "Allocate environment handle error.\n"); return (-1); } /* 設置使用的ODBC版本 */ rc = SQLSetEnvAttr(envh, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0); if (rc != SQL_SUCCESS) { fprintf(stderr, "Set ODBC version error.\n"); goto free_handle_exit; } /* 分配連接句柄 */ rc = SQLAllocHandle(SQL_HANDLE_DBC, envh, &dbch); if (rc != SQL_SUCCESS) { fprintf(stderr, "Allocate DB connection handle error.\n"); goto free_handle_exit; } /* 設置連接數據庫的超時時間為10秒 */ rc = SQLSetConnectAttr(dbch, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER)10, 0); if (rc != SQL_SUCCESS) { fprintf(stderr, "Set connection timeout value error.\n"); goto free_handle_exit; } /* 連接到數據庫,dsn_str是數據源名稱,username是連接用戶,passwd是驗證密碼 * SQL_NTS表示NULL結尾的字符串,自動計算長度 */ rc = SQLConnect(dbch, dsn_str, SQL_NTS, username, SQL_NTS, passwd, SQL_NTS); if (rc != SQL_SUCCESS) { fprintf(stderr, "Connect to DB error.\n"); goto free_handle_exit; } fprintf(stdout, "Database connection established ......\n"); return (0); free_handle_exit: if (dbch != NULL) { /* 釋放連接句柄 */ SQLFreeHandle(SQL_HANDLE_DBC, dbch); } if (envh != NULL) { /* 釋放環境句柄 */ SQLFreeHandle(SQL_HANDLE_ENV, envh); } return (-1); }

浙公網安備 33010602011771號