在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;
}
相關文章
相關標籤/搜索