在linux oracle精简客户端下编译oci程序ociTest.cpp时由于选项次序引起的问题

本文通过一个具体的示例介绍了如何使用 Oracle Call Interface (OCI) 进行数据库操作,包括环境初始化、服务器连接、会话建立及 SQL 查询与插入操作。

:~/prg/embc/ora$ g++ -I${ORACLE_HOME}/sdk/include  -L${ORACLE_HOME}/lib -lclntsh -o ociTest ociTest.cpp

/tmp/ccb8nVWk.o:在函数‘main’中:

ociTest.cpp:(.text+0xcf):对‘OCIEnvCreate’未定义的引用

ociTest.cpp:(.text+0x14f):对‘OCIHandleAlloc’未定义的引用

ociTest.cpp:(.text+0x175):对‘OCIHandleAlloc’未定义的引用

ociTest.cpp:(.text+0x1be):对‘OCIServerAttach’未定义的引用

ociTest.cpp:(.text+0x22c):对‘OCIErrorGet’未定义的引用

ociTest.cpp:(.text+0x27a):对‘OCIHandleFree’未定义的引用

ociTest.cpp:(.text+0x28e):对‘OCIHandleFree’未定义的引用

ociTest.cpp:(.text+0x2a2):对‘OCIHandleFree’未定义的引用

ociTest.cpp:(.text+0x36b):对‘OCIHandleAlloc’未定义的引用

ociTest.cpp:(.text+0x391):对‘OCIHandleAlloc’未定义的引用

ociTest.cpp:(.text+0x3c1):对‘OCIAttrSet’未定义的引用

ociTest.cpp:(.text+0x3e7):对‘OCIHandleAlloc’未定义的引用

ociTest.cpp:(.text+0x438):对‘OCIAttrSet’未定义的引用

ociTest.cpp:(.text+0x489):对‘OCIAttrSet’未定义的引用

ociTest.cpp:(.text+0x4b1):对‘OCISessionBegin’未定义的引用

ociTest.cpp:(.text+0x514):对‘OCIErrorGet’未定义的引用

ociTest.cpp:(.text+0x562):对‘OCIHandleFree’未定义的引用

ociTest.cpp:(.text+0x576):对‘OCIHandleFree’未定义的引用

ociTest.cpp:(.text+0x58a):对‘OCIHandleFree’未定义的引用

ociTest.cpp:(.text+0x5e0):对‘OCIAttrSet’未定义的引用

ociTest.cpp:(.text+0x611):对‘OCIHandleAlloc’未定义的引用

ociTest.cpp:(.text+0x682):对‘OCIHandleAlloc’未定义的引用

ociTest.cpp:(.text+0x727):对‘OCIStmtPrepare’未定义的引用

ociTest.cpp:(.text+0x824):对‘OCIDefineByPos’未定义的引用

ociTest.cpp:(.text+0x887):对‘OCIDefineByPos’未定义的引用

ociTest.cpp:(.text+0x8b7):对‘OCIAttrGet’未定义的引用

ociTest.cpp:(.text+0x8f5):对‘OCIStmtExecute’未定义的引用

ociTest.cpp:(.text+0x967):对‘OCIStmtFetch2’未定义的引用

ociTest.cpp:(.text+0x9a1):对‘OCIAttrGet’未定义的引用

ociTest.cpp:(.text+0x9f3):对‘OCIHandleAlloc’未定义的引用

ociTest.cpp:(.text+0xa64):对‘OCIHandleAlloc’未定义的引用

ociTest.cpp:(.text+0xb42):对‘OCIStmtPrepare’未定义的引用

ociTest.cpp:(.text+0xbdd):对‘OCIStmtExecute’未定义的引用

ociTest.cpp:(.text+0xbf6):对‘OCILogoff’未定义的引用

ociTest.cpp:(.text+0xc14):对‘OCIServerDetach’未定义的引用

ociTest.cpp:(.text+0xc28):对‘OCIHandleFree’未定义的引用

ociTest.cpp:(.text+0xc3c):对‘OCIHandleFree’未定义的引用

ociTest.cpp:(.text+0xc50):对‘OCIHandleFree’未定义的引用

ociTest.cpp:(.text+0xc64):对‘OCIHandleFree’未定义的引用

collect2: error: ld returned 1 exit status

~/prg/embc/ora$ g++ -o ociTest ociTest.cpp -I${ORACLE_HOME}/sdk/include  -L${ORACLE_HOME}/lib -lclntsh

~/prg/embc/ora$ ./ociTest 

Oracle environment initialization success!

Oracle server attach success!

user session success!

Create stmt success !

Create prepare success!

  

7369 SMITH 

7499 ALLEN 

7521 WARD 

7566 JONES 

7654 MARTIN 

7698 BLAKE 

7782 CLARK 

7788 SCOTT 

7839 KING 

7844 TURNER 

7876 ADAMS 

7900 JAMES 

7902 FORD 

7934 MILLER 

 rows :14

Create stmt success !

Create prepare success!

 

ociTest.cpp

// g++ -I${ORACLE_HOME}/sdk/include -o ociTest ociTest.cpp -L${ORACLE_HOME}/lib -lclntsh
#include <oci.h>
#include <iostream>
#include <string>
#include <string.h>
#include <stdlib.h>
using namespace std;

//存放查询数据的结构体
struct result
{
    char ename[20];
    char cname[20];
    result()
    {
        memset(ename, '\0', sizeof(ename));
        memset(cname, '\0', sizeof(cname));
    }
};
 
int main()
{
    // 初始化 OCI 环境句柄指针
    OCIEnv *envhpp = NULL;
    // 初始化服务器句柄
    OCIServer *servhpp = NULL;
    // 用于捕获 OCI 错误信息
    OCIError *errhpp = NULL;
    // 初始化会话句柄
    OCISession *usrhpp = NULL;
    // 初始化服务上下文句柄
    OCISvcCtx *svchpp = NULL;
    // 初始化表达式句柄
    OCIStmt *stmthpp = NULL;
 
    string server="winorcl";
 
    // 创建 OCI 环境 , 并设置环境句柄。
    sword swResult = OCIEnvCreate(&envhpp, OCI_DEFAULT, NULL, NULL, NULL, NULL, 0, NULL);
    if (swResult != OCI_SUCCESS && swResult != OCI_SUCCESS_WITH_INFO)
    {
        cout << "Oracle environment initialization error!" << endl;
        exit(1);
    }
    cout << "Oracle environment initialization success!" << endl;
 
    // 创建错误句柄
    OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&errhpp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0);
 
    // 创建服务句柄
    OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&servhpp, OCI_HTYPE_SERVER, (size_t)0, (dvoid **)0);
 
    // 连接服务器,如果失败则获取错误码
    if (OCIServerAttach(servhpp, errhpp, (text *)server.c_str(), strlen(server.c_str()), 0) != OCI_SUCCESS)
    {
        int errcno;
        char errbuf[512] = "";
        sb4 errcode;
 
        // 获取错误指针和 OCI 错误代码
        OCIErrorGet((dvoid *)errhpp, (ub4)1, (text *)NULL, &errcode, (ub1 *)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
        errcno = errcode;
 
        cout << "Oracle server attach error:" << errbuf << endl;
        OCIHandleFree((dvoid *)envhpp,OCI_HTYPE_ENV);
        OCIHandleFree((dvoid *)servhpp,OCI_HTYPE_SERVER);
        OCIHandleFree((dvoid *)errhpp,OCI_HTYPE_ERROR);
        exit(1);
    }
    cout << "Oracle server attach success!"<< endl;
 
    /***************** 连接数据库 ****************/
    string user = "scott";
    string pas = "tiger";
    errhpp = NULL;
 
    // 创建错误句柄
    (void) OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&errhpp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0);
    // 创建服务上下文句柄
    (void) OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&svchpp, OCI_HTYPE_SVCCTX, (size_t) 0, (dvoid **)0);
    // 设置属性
    (void) OCIAttrSet((dvoid *)svchpp, OCI_HTYPE_SVCCTX, (dvoid *)servhpp, (ub4)0, OCI_ATTR_SERVER, (OCIError *)errhpp);
    // 创建用户连接句柄
    (void) OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&usrhpp, (ub4)OCI_HTYPE_SESSION, (size_t) 0, (dvoid **)0);
    // 设置用户名、密码
    (void) OCIAttrSet((dvoid *)usrhpp, (ub4)OCI_HTYPE_SESSION, (dvoid *)user.c_str(), (ub4)strlen(user.c_str()), (ub4)OCI_ATTR_USERNAME, errhpp);
    (void) OCIAttrSet((dvoid *)usrhpp, (ub4)OCI_HTYPE_SESSION, (dvoid *)pas.c_str(), (ub4)strlen(pas.c_str()), (ub4)OCI_ATTR_PASSWORD, errhpp);
 
    // 创建会话连接
    if(OCISessionBegin(svchpp, errhpp, usrhpp, OCI_CRED_RDBMS, (ub4)OCI_DEFAULT) != OCI_SUCCESS)
    {
        int errcno;
        char errbuf[512]={'\0'};
        sb4 errcode;
        
        // 获取错误指针和 OCI 错误代码
        OCIErrorGet((dvoid *)errhpp, (ub4)1, (text *)NULL, &errcode, (ub1 *)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
        errcno = errcode;
        cout << "User session error:" << errbuf << endl;
        OCIHandleFree((dvoid *)errhpp,OCI_HTYPE_ERROR);
        OCIHandleFree((dvoid *)usrhpp,OCI_HTYPE_SESSION);
        OCIHandleFree((dvoid *)svchpp,OCI_HTYPE_SVCCTX);
        exit(1); 
    }
    cout << "user session success!" << endl;
    
    (void) OCIAttrSet((dvoid *)svchpp, (ub4) OCI_HTYPE_SVCCTX, (dvoid *)usrhpp, (ub4)0, (ub4)OCI_ATTR_SESSION, errhpp);
 
    /*************** 执行 查询SQL 语句 ******************/
    errhpp = NULL;
 
    // 创建一个表达式句柄
    if (OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&stmthpp, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0) != OCI_SUCCESS)
    {
        cout << "Create STMT error !" << endl;
        exit(1);
    }
    cout << "Create stmt success !" << endl;
    
    // 创建错误句柄
    OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&errhpp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0);
    
    // Select语句
    char sql[255] = "select EMPNO,ENAME from emp ";
    
    if (OCIStmtPrepare(stmthpp, errhpp, (text *)sql, (ub4)strlen(sql), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT) != OCI_SUCCESS)
    {
         cout << "Create prepare error!" << sql << endl;
         exit(1);
    }
    cout << "Create prepare success!" << endl;
 
    /********* 绑定参数 ***********/
    // 申请绑定字段的句柄
    OCIDefine *bhp1 = NULL;
    OCIDefine *bhp2 = NULL;
    
    // 存放数据的结构
    struct result rst;
    
    // 指定提取数据长度
    ub2 datalen = 0;
    // 定义指示器变量 , 用于取可能存在空值的字段
    char isnul[6] = "";
    // 定义输出变量 ,
    OCIDefineByPos(stmthpp, &bhp1, errhpp, 1, (dvoid *)&rst.ename, sizeof(rst.ename), SQLT_CHR, NULL, &datalen, NULL, OCI_DEFAULT);
    OCIDefineByPos(stmthpp, &bhp2, errhpp, 2, (dvoid *)&rst.cname, sizeof(rst.cname), SQLT_STR, NULL, &datalen, NULL, OCI_DEFAULT);
 
    // 获取 SQL 语句类型
    ub2 stmt_type;
    OCIAttrGet ((dvoid *)stmthpp, (ub4)OCI_HTYPE_STMT, (dvoid *)&stmt_type, (ub4 *)0, (ub4)OCI_ATTR_STMT_TYPE, errhpp);
    
    // 执行 SQL 语句
    OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)0, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, OCI_DEFAULT);
 
    // 获取查询信息
    int rows_fetched;
    do
    {
        cerr << rst.ename<< " ";
        cerr << rst.cname<< " \n";
    }
    while(OCIStmtFetch2(stmthpp, errhpp, 1, OCI_FETCH_NEXT, 1, OCI_DEFAULT) != OCI_NO_DATA);
 
    // 获得记录条数
    OCIAttrGet((CONST void *)stmthpp, OCI_HTYPE_STMT, (void *)&rows_fetched, (ub4 *)sizeof(rows_fetched), OCI_ATTR_ROW_COUNT, errhpp);
    cout << " rows :" << rows_fetched << endl;
 
    /*************** 执行 新增SQL 语句 ******************/
    if (OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&stmthpp, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0) != OCI_SUCCESS)
    {
        cout << "Create STMT error !" << endl;
        exit(1);
    }
    cout << "Create stmt success !" << endl;
 
    OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&errhpp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0);
 
    // Insert语句
    char sql2[255] = "insert into emp (EMPNO,ENAME) values(7900 , 'testoci')";
    
    // 准备Sql语句
    if (OCIStmtPrepare(stmthpp, errhpp, (text *)sql2, (ub4)strlen(sql2), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT) != OCI_SUCCESS)
    {
         cout << "Create prepare error!" << sql2 << endl;
         exit(1);
    }
    cout << "Create prepare success!" << endl;
    
    // 执行SQL 语句
    OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)1, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, OCI_DEFAULT);

    // 断开用户会话
    OCILogoff(svchpp, errhpp);
    
    // 断开服务器连接
    OCIServerDetach(servhpp, errhpp, OCI_DEFAULT);
    
    // 释放资源
    OCIHandleFree((dvoid *) stmthpp, OCI_HTYPE_STMT);
    OCIHandleFree((dvoid *) svchpp, OCI_HTYPE_SVCCTX);
    OCIHandleFree((dvoid *) servhpp, OCI_HTYPE_SERVER);
    OCIHandleFree((dvoid *) errhpp, OCI_HTYPE_ERROR);
 
    return 0;
}

 

转载于:https://my.oschina.net/u/2245781/blog/684700

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值