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

前端之家收集整理的这篇文章主要介绍了Oracle调用接口(OCI)源码剖析(3):关闭数据库连接前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

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

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

  1. void CDbCloseDb(void *hDb)
  2. {
  3. CDb *pCDb = NULL;
  4.  
  5. if (NULL == hDb)
  6. {
  7. return;
  8. }
  9. pCDb = (CDb *)hDb;
  10.  
  11. DoDbFree(pCDb->hdbc);
  12. DoRecFree(pCDb->hRec);
  13. OsRetUB((UINT8*)hDb);
  14. return;
  15. }

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

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

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

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

  1. static void DoDbFree(OCIHDBC hdbc)
  2. {
  3. if (NULL == hdbc)
  4. {
  5. return;
  6. }
  7. OCISessionEnd(hdbc->svchp,hdbc->errhp,hdbc->authp,(ub4)0);
  8. OCIServerDetach(hdbc->srvhp,(ub4)OCI_DEFAULT);
  9.  
  10. OCIHandleFree((dvoid *)hdbc->srvhp,(ub4)OCI_HTYPE_SERVER);
  11. OCIHandleFree((dvoid *)hdbc->svchp,(ub4)OCI_HTYPE_SVCCTX);
  12. OCIHandleFree((dvoid *)hdbc->errhp,(ub4)OCI_HTYPE_ERROR);
  13. OCIHandleFree((dvoid *)hdbc->authp,(ub4)OCI_HTYPE_SESSION);
  14. OCIHandleFree((dvoid *)hdbc->envhp,(ub4)OCI_HTYPE_ENV);
  15.  
  16. OsRetUB((UINT8*)hdbc);
  17. hdbc = NULL;
  18. }

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

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

  1. /* 所有OCI主要句柄数据结构 */
  2. typedef struct
  3. {
  4. OCIEnv *envhp; /* 环境句柄 */
  5. OCIError *errhp; /* 错误句柄 */
  6. OCIServer *srvhp; /* 服务器句柄 */
  7. OCISvcCtx *svchp; /* 服务环境句柄 */
  8. OCISession *authp; /* 会话句柄 */
  9. OCIStmt *stmthp; /* 语句句柄 */
  10. }t_envctx;
  11. typedef t_envctx *OCIHDBC;

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

  1. static void DoRecFree(CDbRecordset*hRecordset)
  2. {
  3. if (NULL != hRecordset)
  4. {
  5. OsRetUB((UINT8*)hRecordset);
  6. }
  7. }

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

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

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

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

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

  1. INT32 main(void)
  2. {
  3. INT8 szDBServerName[50] = {0};
  4. INT8 szDBName[50] = {0};
  5. INT8 szDBUser[50] = {0};
  6. INT8 szDBPwd[50] = {0};
  7. INT8 szsqlBuf[100] = {0};
  8. INT8 szRcvBuf[100] = {0};
  9.  
  10. INT32 iRetVal = 0;
  11.  
  12. void *pDBHandle = NULL;
  13.  
  14. // 获取数据库各参数的值
  15. memcpy(szDBServerName,"db192_1_8_13",strlen("db192_1_8_13"));
  16. memcpy(szDBName,"dbp_166",strlen("dbp_166"));
  17. memcpy(szDBUser,strlen("dbp_166"));
  18. memcpy(szDBPwd,strlen("dbp_166"));
  19.  
  20. // 连接数据库
  21. pDBHandle = CDbCreateDb("Oracle",szDBServerName,szDBName,szDBUser,szDBPwd);
  22.  
  23. if (pDBHandle == NULL) // 连接失败
  24. {
  25. printf("ConnectDB Failed! ServiceName:%s,DBName:%s,User:%s,Pwd:%s\n",szDBPwd);
  26.  
  27. return -1;
  28. }
  29.  
  30. printf("ConnectDB success! ServiceName:%s,szDBPwd);
  31. // 执行sql语句并获取结果
  32. // 获取sql语句
  33. memcpy(szsqlBuf,"select Boxnumber from tb_test where id=1",strlen("select Boxnumber from tb_test where id=1"));
  34. // 调用CDbExecsql函数执行sql语句
  35. iRetVal = CDbExecsql(pDBHandle,szsqlBuf);
  36. if (iRetVal != 0) // 执行失败
  37. {
  38. printf("CDbExecsql Failed! RetVal=%d (ServiceName:%s,Pwd:%s)\n",iRetVal,szDBPwd);
  39. return -1;
  40. }
  41. // 调用CDbFetch函数获取数据库返回的结果
  42. iRetVal = CDbFetch(pDBHandle,szRcvBuf,100);
  43. if (iRetVal != 0) // 执行失败
  44. {
  45. printf("CDbFetch Failed! RetVal=%d (ServiceName:%s,szDBPwd);
  46. return -1;
  47. }
  48. // 打印从数据库获取到的结果
  49. printf("RcvBuf=%s\n",szRcvBuf);
  50. // 调用CDbCloseDb函数关闭数据库连接
  51. CDbCloseDb(pDBHandle);
  52. pDBHandle = NULL; // 将数据库句柄指针置为空
  53. return 0;
  54. }

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

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

猜你在找的Oracle相关文章