Oracle OCI :OCI程序设计流程

本文详细介绍了使用Oracle OCI库进行数据库连接和查询的步骤,包括创建环境句柄、分配服务器句柄、设置用户会话属性、执行SQL语句以及释放资源。示例代码展示了如何通过OCI接口连接到Oracle数据库并执行查询操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、创建环境句柄(分配句柄)
2、通过环境句柄分配服务器句柄
3、通过环境句柄分配错误处理句柄
4、测试服务器是否能够被连接(实例化服务器句柄)
5、通过环境句柄分配服务器上下文句柄
6、设置服务器上下文句柄的服务器属性(后面还需要设置其会话属性)
7、通环境句柄分配用户会话句柄
8、设置用户会话句柄的用户名和密码属性
9、建立用户会话连接,测试是否能够连接成功(实例化用户会话句柄)
10、设置服务器上下文的用户会话属性
11、分配语句句柄,准备语句,语句执行等过程
12、结束会话
13、断开连接
14、释放环境句柄

/*
* @Content  : 获取一个查询的结果
****/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oci.h>

#if defined(WIN32)
#pragma comment(lib, "oci.lib")
#endif

//获取错误诊断信息
//@param   : pErr,错误句柄
//           lStatus, 状态码信息
//@return  : 0: 失败,出错
//             1: 成功返回
int CheckErr(OCIError *pErr, sword lStatus);

//数据库服务名
static text* dbname = (text*) "//10.0.4.122:1521/orcl";

//用户及密码
static text* username = (text*) "xiaoming" ;
static text* password =(text*) "XiaoMing123";

//DML(INSERT)操作的SQL语句
//static text* select = (text*) "SELECT id, name, age, address FROM student";
static text* select = (text*) "SELECT id, name, age FROM student";


static char  colname[64] = "";

int main()
{
   
    OCIEnv *envhp; // 环境句柄
    OCIServer *srvhp; //服务器句柄
    OCIError *errhp; //错误句柄
    OCIError *errhp1; //错误句柄
    OCIError *errhp2; //错误句柄
    OCISession *usrhp; //用户会话句柄
    OCISvcCtx *svchp; //服务上下文句柄
    OCIStmt* stmthp; //语句句柄

    //三个定义句柄,用于定义输出结果
    OCIDefine* defhp1;
    OCIDefine* defhp2;
    OCIDefine* defhp3;
    //OCIDefine* defhp4;
   
    //输出变量
    int    nID;
    char szName[128];
    int nAge;
    char szAddress[256];
    sb2 indAddr; //address字段的指示符

    sb4 status = 0;

    ub4 colcount = 0;  //列数

    //使用线程和对象模式来创建环境句柄
    OCIEnvCreate(&envhp, OCI_THREADED|OCI_OBJECT, (dvoid *)0, 0, 0, 0, (size_t) 0, (dvoid **)0);

   //分配服务器句柄
    OCIHandleAlloc ((dvoid *)envhp, (dvoid **)&srvhp, OCI_HTYPE_SERVER, 0, (dvoid **) 0);
  
    //分配错误句柄
    OCIHandleAlloc ((dvoid *)envhp, (dvoid **)&errhp,  OCI_HTYPE_ERROR, 0, (dvoid **) 0);
    OCIHandleAlloc ((dvoid *)envhp, (dvoid **)&errhp1, OCI_HTYPE_ERROR, 0, (dvoid **) 0);
    OCIHandleAlloc ((dvoid *)envhp, (dvoid **)&errhp2, OCI_HTYPE_ERROR, 0, (dvoid **) 0);

    //创建服务器上下文句柄,"orcl"为建立连接的数据库名
    if (OCIServerAttach (srvhp, errhp, (text *)dbname,strlen ((char*)dbname), OCI_DEFAULT) == OCI_SUCCESS)
        printf("\n已经成功连上数据库orcl\n");
    else //终止程序
    {
        printf("\n数据库名字不对,连接数据库失败!\n");
        return -1;
    }
    //分配服务器上下文句柄
    OCIHandleAlloc ((dvoid *)envhp, (dvoid **)&svchp, OCI_HTYPE_SVCCTX, 0, (dvoid **) 0);

    //设置服务器上下文句柄的服务器句柄属性
    OCIAttrSet ((dvoid *)svchp, OCI_HTYPE_SVCCTX,(dvoid *)srvhp, (ub4) 0, OCI_ATTR_SERVER, errhp);
    //分配用户会话句柄
    OCIHandleAlloc ((dvoid *)envhp, (dvoid **)&usrhp,OCI_HTYPE_SESSION, 0, (dvoid **) 0);
    //为用户会话句柄设置用户名和密码属性
    OCIAttrSet ((dvoid *)usrhp, OCI_HTYPE_SESSION,(dvoid *)username, (ub4)strlen((char*)username), OCI_ATTR_USERNAME, errhp);
    OCIAttrSet ((dvoid *)usrhp, OCI_HTYPE_SESSION,(dvoid *)password, (ub4)strlen((char*)password), OCI_ATTR_PASSWORD, errhp);
    if (OCISessionBegin ( svchp, errhp, usrhp, OCI_CRED_RDBMS, OCI_DEFAULT) == OCI_SUCCESS)
    {
        printf("成功建立用户会话!\n");
    }
    else
    {
        printf("建立用户会话失败!\n");
        return -1;
    }
    //在服务器上下文环境中设置用户会话属性
    OCIAttrSet ( (dvoid *)svchp, OCI_HTYPE_SVCCTX,(dvoid *)usrhp, (ub4) 0, OCI_ATTR_SESSION, errhp);
    //分配语句句柄
    CheckErr(errhp, OCIHandleAlloc(envhp, (void**)&stmthp, OCI_HTYPE_STMT, 0, 0));

    //设置预取数量为10
    int fetchCount = 10;
    CheckErr(errhp, OCIAttrSet(stmthp, OCI_HTYPE_STMT, (void*)&fetchCount, 4, OCI_ATTR_PREFETCH_ROWS, errhp));
    //准备SQL语句
    CheckErr(errhp, OCIStmtPrepare(stmthp, errhp, select, strlen((char*)select), OCI_NTV_SYNTAX, OCI_DEFAULT));

    //定义输出
    CheckErr(errhp, OCIDefineByPos(stmthp, &defhp1, errhp, 1, &nID, sizeof(nID), SQLT_INT, 0, 0, 0, OCI_DEFAULT));
    CheckErr(errhp, OCIDefineByPos(stmthp, &defhp2, errhp, 2, szName, 33, SQLT_STR, 0, 0, 0, OCI_DEFAULT));
    CheckErr(errhp, OCIDefineByPos(stmthp, &defhp3, errhp, 3, &nAge, sizeof(nAge),SQLT_INT, 0, 0, 0, OCI_DEFAULT));
    /*CheckErr(errhp, OCIDefineByPos(stmthp, &defhp4, errhp, 4, szAddress, 129, SQLT_STR, &indAddr, 0, 0, OCI_DEFAULT));*/

    //提取结果
    CheckErr(errhp, OCIStmtExecute(svchp, stmthp, errhp, 0, 0, NULL, NULL,OCI_DEFAULT));

    printf("\n查询结果为: \n");
    printf("ID      NAME            AGE     ADDRESS\n");
    printf("---------------------------------------------------\n");
    while( OCI_NO_DATA != OCIStmtFetch(stmthp, errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT))
    {
        printf("%-8d%-16s%-8d", nID, szName, nAge);
        /*if(indAddr == 0) printf("%-32s", szAddress);*/
        printf("\n");
    }
    printf("结束会话和数据库连接!\n");
    //结束会话
    OCISessionEnd(svchp, errhp, usrhp, OCI_DEFAULT);
    //断开连接
    OCIServerDetach(srvhp, errhp, OCI_DEFAULT);
    //释放环境句柄
    OCIHandleFree((void*)envhp, OCI_HTYPE_ENV);
    int nTemp;
    scanf("%d", &nTemp);
    return 0;
}

int CheckErr(OCIError *pErr, sword lStatus)
{
   
    sb4        m_s_nErrCode = 0;
    char    m_s_szErr[512];
   
    switch (lStatus)
    {
    case OCI_SUCCESS:
        strcpy(m_s_szErr,"OCI_SUCCESS");   
        break;
    case OCI_SUCCESS_WITH_INFO:
        strcpy(m_s_szErr, "OCI_SUCCESS_WITH_INFO");
        printf("OCI Error: %s\n", m_s_szErr);
        break;
    case OCI_ERROR:
        OCIErrorGet((dvoid *)pErr, (ub4)1, (text *)NULL, &m_s_nErrCode, (unsigned char*)m_s_szErr, (ub4)sizeof(m_s_szErr), OCI_HTYPE_ERROR);
        printf("OCI Error: %s\n", m_s_szErr);
        break;
    case OCI_NEED_DATA:
        strcpy(m_s_szErr, "OCI_NEED_DATA");
        printf("OCI Error: %s\n", m_s_szErr);
        break;
    case OCI_NO_DATA:
        strcpy(m_s_szErr, "OCI_NO_DATA");
        printf("OCI Error: %s\n", m_s_szErr);
        break;
    case OCI_INVALID_HANDLE:
        strcpy(m_s_szErr, "OCI_INVALID_HANDLE");
        printf("OCI Error: %s\n", m_s_szErr);
        break;
    case OCI_STILL_EXECUTING:
        strcpy(m_s_szErr, "OCI_STILL_EXECUTING");
        printf("OCI Error: %s\n", m_s_szErr);
        break;
    case OCI_CONTINUE:
        strcpy(m_s_szErr, "OCI_CONTINUE");
        printf("OCI Error: %s\n", m_s_szErr);
        break;
    default:
        break;
    }

    if (lStatus != OCI_SUCCESS && lStatus != OCI_SUCCESS_WITH_INFO)
    {
        return 0;  //确实有错误
    }
    else
    {
        return 1;  //没有检查到错误
    }
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值