首页 > 解决方案 > 如何从 C 程序中使用 OCIServerVersion (Oracle)?

问题描述

仅供参考:此代码是用于数据库访问的开源 LabView LLB/库/DLL 的一部分

我的代码段如下:

#ifdef HAVE_ORACLE
    case oracle_api:
        sprintf(DriverName, "%s\nOracle ", SQL_LV_VERSION);
        retCode = OCIServerVersion (db->srvhp, db->errhp, DriverName + strlen(DriverName), BUFF_SIZE - strlen(DriverName), 0);
        checkerr(db->errhp, retCode, DriverName + strlen(DriverName)); 
        break;
#endif

问题是我不断收到“OCI_INVALID_HANDLE”。

来自 GDB:

(gdb) print retCode
$1 = -2
(gdb) print DriverName
$2 = "sql_LV-1.10\nOracle Error - OCI_INVALID_HANDLE\n\000
(gdb) whatis db->srvhp
type = OCIServer *

我的 typedef 是:

/* Typedefs */  
typedef struct {
    MYSQL mysql;
    MYSQL_RES *query_results;
#ifdef HAVE_ODBC
    HENV henv;
    HDBC hdbc;
    HSTMT hstmt;
#endif
#ifdef HAVE_ORACLE
    OCIEnv *envhp;
    OCIError *errhp;
    OCISession *authp;
    OCIServer *srvhp;
    OCISvcCtx *svchp;
#endif
    unsigned short int odbc_driver, db_type;
    } SQL_LV_REF;

我尝试了服务上下文句柄和服务器上下文句柄(它们都是非 NULL)。

而且我已经能够使用打开的连接在单独的 DLL 调用中成功地“选择”数据。

回答这个问题,OCIServerAttach 是什么样的?

#ifdef HAVE_ORACLE
case oracle_api:
    sprintf(EasyConnect, "%s:%d/%s", host, (port==0) ? 1521: port, db_nm);
    retCode = OCIEnvCreate((OCIEnv **) &db_ref->envhp, (ub4) OCI_DEFAULT,
                (dvoid *) 0, (dvoid * (*)(dvoid *,size_t)) 0,
                (dvoid * (*)(dvoid *, dvoid *, size_t)) 0,
                (void (*)(dvoid *, dvoid *)) 0, (size_t) 0, (dvoid **) 0);

        if (retCode != 0) {
            (void) sprintf(debug_str, "OCIEnvCreate failed with retCode = %d.\n", retCode);
            LV_str_cp(debug, debug_str); return(-1);}

        (void) OCIHandleAlloc( (dvoid *) db_ref->envhp, (dvoid **) &db_ref->errhp, OCI_HTYPE_ERROR,
                (size_t) 0, (dvoid **) 0);   /* server contexts */
        (void) OCIHandleAlloc( (dvoid *) db_ref->envhp, (dvoid **) &db_ref->srvhp, OCI_HTYPE_SERVER,
                        (size_t) 0, (dvoid **) 0);
        (void) OCIHandleAlloc( (dvoid *) db_ref->envhp, (dvoid **) &db_ref->svchp, OCI_HTYPE_SVCCTX,
                        (size_t) 0, (dvoid **) 0);
        retCode =  OCIServerAttach( db_ref->srvhp, db_ref->errhp, (text *) EasyConnect,    /* Connect to the target */
                                    strlen((const char *) EasyConnect), 0);

标签: coracleoracle-call-interface

解决方案


我知道这是一篇旧帖子,但由于这个问题/答案出现在 google 搜索中,所以为追随我的人回答它:) OCI API 真的没有什么魔力——你在几乎所有的 API 中都使用相同的技术。获取oracle服务器版本所需要做的就是以下

sword rc;
char sver[1024];

if((rc = OCIServerVersion(_service, _error, (text*) sver, (ub4) sizeof(sver), (ub1) OCI_HTYPE_SVCCTX)) != OCI_SUCCESS)
    throw "OCIServerVersion";

std::cout<<"database version:"<<sver;

这里

OCISvcCtx *_service;
OCIError *_error;

在调用 API 之前,您只需要确保正确建立连接以获取服务器版本。


推荐阅读