Oracle调用接口(OCI)源码剖析(3):关闭数据库连接

概述
继创建数据库连接和履行SQL语句并获得结果以后,我们继续对OCI中关闭数据库连接的源码进行剖析。该操作主要是由CDbCloseDb函数完成的。

下面对这个函数的源码进行分析。

OCI中履行关闭数据库连接的源码剖析
在OCI中,CDbCloseDb函数的代码以下:

void CDbCloseDb(void *hDb)
{
CDb *pCDb = NULL;

if (NULL == hDb)
{
return;
}
pCDb = (CDb *)hDb;

DoDbFree(pCDb->hdbc);
DoRecFree(pCDb->hRec);
OsRetUB((UINT8*)hDb);
return;
}

从该函数的代码实现中,我们可以看到:
1)该函数的输入参数只有1个:数据库连接句柄。同时,该函数还调用了3个函数,DoDbFree用于释放数据库连接,DoRecFree用于释放数据库结果集行数据缓冲区,OsRetUB用于释放操作系统的数据库内存。

2)CDb结构体用于寄存数据库连接句柄数据,其声明以下:

typedef struct CDbTag
{
INT32 iDbType; /* 数据库类型 0:sqlservr1:sybase 2:oracle*/
OCIHDBC hdbc; /* 全局OCI句柄 */
CDbRecordset *hRec; /* 行结果集数据结构指针 */
}CDb;

释放数据库连接的DoDbFree函数的代码以下:

static void DoDbFree(OCIHDBC hdbc)
{
if (NULL == hdbc)
{
return;
}
OCISessionEnd(hdbc->svchp, hdbc->errhp, hdbc->authp, (ub4)0);
OCIServerDetach(hdbc->srvhp, hdbc->errhp, (ub4)OCI_DEFAULT);

OCIHandleFree((dvoid *)hdbc->srvhp, (ub4)OCI_HTYPE_SERVER);
OCIHandleFree((dvoid *)hdbc->svchp, (ub4)OCI_HTYPE_SVCCTX);
OCIHandleFree((dvoid *)hdbc->errhp, (ub4)OCI_HTYPE_ERROR);
OCIHandleFree((dvoid *)hdbc->authp, (ub4)OCI_HTYPE_SESSION);
OCIHandleFree((dvoid *)hdbc->envhp, (ub4)OCI_HTYPE_ENV);

OsRetUB((UINT8*)hdbc);
hdbc = NULL;
}

从该函数的代码实现中,我们可以看到:
1)该函数调用OCI底层的函数来分别释放与数据库相干的句柄,这些句柄定义在OCIHDBC结构体中。

2)OCIHDBC结构体的声明以下:

/* 所有OCI主要句柄数据结构 */
typedef struct
{
OCIEnv *envhp; /* 环境句柄 */
OCIError *errhp; /* 毛病句柄 */
OCIServer *srvhp; /* 服务器句柄 */
OCISvcCtx *svchp; /* 服务环境句柄 */
OCISession *authp; /* 会话句柄 */
OCIStmt *stmthp; /* 语句句柄 */
}t_envctx;
typedef t_envctx *OCIHDBC;

释放数据库结果集行数据缓冲区的DoRecFree函数的代码以下:

static void DoRecFree(CDbRecordset*hRecordset)
{
if (NULL != hRecordset)
{
OsRetUB((UINT8*)hRecordset);
}
}

从该函数的代码实现中,我们可以看到:
1)该函数调用OsRetUB函数来释放数据缓冲区。

2)结果集行数据结构体的声明以下:

typedef struct CDbRecordsetTag
{
void *cmd; /* 命令缓冲区 */
int sqltype; /* 1:select 2:other*/
int colCount; /* 返回列数 */
char colfieldname[CDB_MAX_COL_NUM][40];/*每列列名 */
int colfieldlength[CDB_MAX_COL_NUM]; /* 列名宽度 */
int pColWidth[CDB_MAX_COL_NUM]; /* 每列宽度 */
int pColType[CDB_MAX_COL_NUM]; /* 列类型 */
char pRecordBuf[CDB_MAX_COL_NUM][CDB_MAX_COL_WIDTH];/* 列数据 */
int pRetColWidth[CDB_MAX_COL_NUM];
short pRetIndicator[CDB_MAX_COL_NUM];
} CDbRecordset;

关闭数据库连接CDbCloseDb函数调用
当我们获得到了数据库的返回结果以后,如果不再需要使用数据库了,那末就要调用CDbCloseDb函数关闭数据库连接。

CDbCloseDb函数调用的示例代码以下:

INT32 main(void)
{
INT8 szDBServerName[50] = {0};
INT8 szDBName[50] = {0};
INT8 szDBUser[50] = {0};
INT8 szDBPwd[50] = {0};
INT8 szSqlBuf[100] = {0};
INT8 szRcvBuf[100] = {0};

INT32 iRetVal = 0;

void *pDBHandle = NULL;

// 获得数据库各参数的值
memcpy(szDBServerName, "db192_1_8_13",strlen("db192_1_8_13"));
memcpy(szDBName, "dbp_166", strlen("dbp_166"));
memcpy(szDBUser, "dbp_166", strlen("dbp_166"));
memcpy(szDBPwd, "dbp_166", strlen("dbp_166"));

// 连接数据库
pDBHandle = CDbCreateDb("Oracle", szDBServerName, szDBName, szDBUser,szDBPwd);

if (pDBHandle == NULL) // 连接失败
{
printf("ConnectDB failed! ServiceName:%s, DBName:%s, User:%s,Pwd:%s\n", szDBServerName, szDBName, szDBUser, szDBPwd);

return -1;
}

printf("ConnectDB success! ServiceName:%s, DBName:%s, User:%s,Pwd:%s\n", szDBServerName, szDBName, szDBUser, szDBPwd);

// 履行SQL语句并获得结果
// 获得SQL语句
memcpy(szSqlBuf, "select boxnumber from tb_test where id=1",strlen("select boxnumber from tb_test where id=1"));

// 调用CDbExecSql函数履行SQL语句
iRetVal = CDbExecSql(pDBHandle, szSqlBuf);
if (iRetVal != 0) // 履行失败
{
printf("CDbExecSql failed! RetVal=%d (ServiceName:%s, DBName:%s,User:%s, Pwd:%s)\n", iRetVal, szDBServerName, szDBName, szDBUser, szDBPwd);

return -1;
}

// 调用CDbFetch函数获得数据库返回的结果
iRetVal = CDbFetch(pDBHandle, szRcvBuf, 100);
if (iRetVal != 0) // 履行失败
{
printf("CDbFetch failed! RetVal=%d (ServiceName:%s, DBName:%s,User:%s, Pwd:%s)\n", iRetVal, szDBServerName, szDBName, szDBUser,szDBPwd);

return -1;
}

// 打印从数据库中获得到的结果
printf("RcvBuf=%s\n", szRcvBuf);

// 调用CDbCloseDb函数关闭数据库连接
CDbCloseDb(pDBHandle);
pDBHandle = NULL; // 将数据库句柄指针置为空

return 0;
}

说明:
1)CDbCloseDb函数的输入参数是:数据库句柄指针,数据库句柄是由CDbCreateDb函数履行以后取得的。

2)CDbCloseDb函数履行完成以后,还要单独编写语句将数据库句柄指针置为空,避免该指针在后面的流程中被随便使用。

波比源码 – 精品源码模版分享 | www.bobi11.com
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!

波比源码 » Oracle调用接口(OCI)源码剖析(3):关闭数据库连接

发表评论

Hi, 如果你对这款模板有疑问,可以跟我联系哦!

联系站长
赞助VIP 享更多特权,建议使用 QQ 登录
喜欢我嘛?喜欢就按“ctrl+D”收藏我吧!♡