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

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

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

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

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

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

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

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

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

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

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

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;
}
相关文章
相关标签/搜索