oracle去除OIC信号,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)该函数的输入参数只有一个:数据库连接句柄。同时,该函数还调用了三个函数,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函数执行完成之后,还要单独编写语句将数据库句柄指针置为空,防止该指针在后面的流程中被随意使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值