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

简介: 概述 继创建数据库连接和执行SQL语句并获取结果之后,我们继续对OCI中关闭数据库连接的源码进行剖析。

概述
继创建数据库连接和执行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;
}
AI 代码解读

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

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

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

释放数据库连接的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;
}
AI 代码解读

从该函数的代码实现中,我们可以看到:
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;
AI 代码解读

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

static void DoRecFree(CDbRecordset*hRecordset)
{
   if (NULL != hRecordset)
   {
       OsRetUB((UINT8*)hRecordset);
   }
}
AI 代码解读

从该函数的代码实现中,我们可以看到:
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;
AI 代码解读

关闭数据库连接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;
}
AI 代码解读

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

2)CDbCloseDb函数执行完成之后,还要单独编写语句将数据库句柄指针置为空,防止该指针在后面的流程中被随意使用。

目录
打赏
0
0
0
0
260
分享
相关文章
循序渐进丨MogDB 中 gs_dump 数据库导出工具源码概览
通过这种循序渐进的方式,您可以深入理解 `gs_dump` 的实现,并根据需要进行定制和优化。这不仅有助于提升数据库管理的效率,还能为数据迁移和备份提供可靠的保障。
22 3
基于SpringBoot+Vue实现的大学生就业服务平台设计与实现(系统源码+文档+数据库+部署等)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
87 6
基于SpringBoot+Vue的班级综合测评管理系统设计与实现(系统源码+文档+数据库+部署等)
✌免费选题、功能需求设计、任务书、开题报告、中期检查、程序功能实现、论文辅导、论文降重、答辩PPT辅导、会议视频一对一讲解代码等✌
57 4
基于SpringBoot+Vue实现的大学生体质测试管理系统设计与实现(系统源码+文档+数据库+部署)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
49 2
基于SpringBoot+Vue实现的冬奥会科普平台设计与实现(系统源码+文档+数据库+部署)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
57 0
数据库数据恢复—ORACLE常见故障的数据恢复方案
Oracle数据库常见故障表现: 1、ORACLE数据库无法启动或无法正常工作。 2、ORACLE ASM存储破坏。 3、ORACLE数据文件丢失。 4、ORACLE数据文件部分损坏。 5、ORACLE DUMP文件损坏。
169 11
Oracle数据恢复—Oracle数据库文件有坏快损坏的数据恢复案例
一台Oracle数据库打开报错,报错信息: “system01.dbf需要更多的恢复来保持一致性,数据库无法打开”。管理员联系我们数据恢复中心寻求帮助,并提供了Oracle_Home目录的所有文件。用户方要求恢复zxfg用户下的数据。 由于数据库没有备份,无法通过备份去恢复数据库。
oracle数据恢复—Oracle数据库文件大小变为0kb的数据恢复案例
存储掉盘超过上限,lun无法识别。管理员重组存储的位图信息并导出lun,发现linux操作系统上部署的oracle数据库中有上百个数据文件的大小变为0kb。数据库的大小缩水了80%以上。 取出&并分析oracle数据库的控制文件。重组存储位图信息,重新导出控制文件中记录的数据文件,发现这些文件的大小依然为0kb。
数据库常用接口
ODBC(Open Database Connectivity):开放数据库互连技术为访问不同的SQL数据库提供了一个共同的接口。ODBC使用SQL作为访问数据的标准。这一接口提供了最大限度的互操作性,一个应用程序可以通过共同的一组代码访问不同的SQL数据库管理系统(DBMS)。 一个基于ODBC的应用程序对数据库的操作不依赖任何DBMS,不直接与DBMS打交道,所有的数据库操作由对应的DBMS的ODBC驱动程序完成。也就是说,不论是Access,MySQL还是Oracle数据库,均可用ODBC API进行访问。由此可见,ODBC的最大优点是能以统一的方式处理所有的数据库。
Oracle数据库优化方法
【10月更文挑战第25天】Oracle数据库优化方法
83 7

热门文章

最新文章

推荐镜像

更多