通过oci连接数据库,可以获得表结构的信息,例如对于表test("id" INTERGER,"num" INTERGER)可以获得表有两列,两列的数据结构分别为SQLT_INT,但是希望读取表结构的表项信息时总是为空,都是返回OCI_NO_DATA,但是表结构中是有几项信息的,请问是为什么?而且用的oracle spatial与oci高级编程中的实例插入的时候返回OCI_ERROR,刚开始接触oci,希望大家能帮忙#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oci.h>int CheckErr(OCIError *pErr, sword lStatus);static text* dbname = (text*) "wangf";static text* username = (text*) "system";
static text* password = (text*) "softraid";static text* insert1 = (text*) "INSERT INTO test(id, num)  VALUES(5, 5)";static text* insert2 = (text*) "INSERT INTO test (id, num) VALUES(6, 6)";
int main()
{

OCIEnv *myenvhp; // 环境句柄
OCIServer *mysrvhp; //服务器句柄
OCIError *myerrhp; //错误句柄
OCIError *myerrhp1; //错误句柄
OCIError *myerrhp2; //错误句柄
OCISession *myusrhp; //用户会话句柄
OCISvcCtx *mysvchp; //服务上下文句柄
OCIStmt* stmthp; //语句句柄 OCIBind* bndhp1 = NULL;
OCIBind* bndhp2 = NULL; int nSID[5] = {1, 2, 1, 1, 3}; //学号
char szName[5][32] = {"Bob", "Ying", "HeXiong", "Jenny", "Mary" }; //姓名
sb4 nNameLen = 32;
sb4 status = 0;
OCIEnvCreate(&myenvhp, OCI_THREADED|OCI_OBJECT, (dvoid *)0,
0, 0, 0, (size_t) 0, (dvoid **)0);
OCIHandleAlloc ((dvoid *)myenvhp, (dvoid **)&mysrvhp,
OCI_HTYPE_SERVER, 0, (dvoid **) 0);
OCIHandleAlloc ((dvoid *)myenvhp, (dvoid **)&myerrhp,
OCI_HTYPE_ERROR, 0, (dvoid **) 0);
OCIHandleAlloc ((dvoid *)myenvhp, (dvoid **)&myerrhp1,
OCI_HTYPE_ERROR, 0, (dvoid **) 0);
OCIHandleAlloc ((dvoid *)myenvhp, (dvoid **)&myerrhp2,
OCI_HTYPE_ERROR, 0, (dvoid **) 0); if (OCIServerAttach (mysrvhp, myerrhp, (text *)dbname,
strlen ((char*)dbname), OCI_DEFAULT) == OCI_SUCCESS)
printf("\n connetc \n");
else //终止程序
{
printf("\n error \n");
return -1;
}
OCIHandleAlloc ((dvoid *)myenvhp, (dvoid **)&mysvchp,
OCI_HTYPE_SVCCTX, 0, (dvoid **) 0);
OCIAttrSet ((dvoid *)mysvchp, OCI_HTYPE_SVCCTX,
(dvoid *)mysrvhp, (ub4) 0, OCI_ATTR_SERVER, myerrhp);
OCIHandleAlloc ((dvoid *)myenvhp, (dvoid **)&myusrhp,
OCI_HTYPE_SESSION, 0, (dvoid **) 0);
OCIAttrSet ((dvoid *)myusrhp, OCI_HTYPE_SESSION,
(dvoid *)username, (ub4)strlen((char*)username),
OCI_ATTR_USERNAME, myerrhp);
OCIAttrSet ((dvoid *)myusrhp, OCI_HTYPE_SESSION,
(dvoid *)password, (ub4)strlen((char*)password),
OCI_ATTR_PASSWORD, myerrhp);
if (OCISessionBegin ( mysvchp, myerrhp, myusrhp,
OCI_CRED_RDBMS, OCI_DEFAULT) == OCI_SUCCESS)
{
printf("ok\n");
}
else
{
printf("failed\n");
return -1;
}
OCIAttrSet ( (dvoid *)mysvchp, OCI_HTYPE_SVCCTX,
(dvoid *)myusrhp, (ub4) 0, OCI_ATTR_SESSION, myerrhp);
CheckErr(myerrhp, OCIHandleAlloc(myenvhp, (void**)&stmthp, OCI_HTYPE_STMT, 0, 0));
CheckErr(myerrhp, OCIStmtPrepare(stmthp, myerrhp, insert1, strlen((char*)insert1),
OCI_NTV_SYNTAX, OCI_DEFAULT)); status = OCIStmtExecute(mysvchp, stmthp, myerrhp, 1, 0, NULL, NULL,
OCI_DEFAULT);
printf("status: %d\n",status);//输出-1,表示OCI_ERROR
if (status && status != OCI_SUCCESS_WITH_INFO)
{
OCIHandleFree((dvoid*)myenvhp, OCI_HTYPE_ENV);
return -1;
}
printf("insert first\n"); OCITransCommit(mysvchp, myerrhp, (ub4) 0);
printf("insert first ok\n");
CheckErr(myerrhp, OCIStmtPrepare(stmthp, myerrhp, insert2, strlen((char*)insert1),
OCI_NTV_SYNTAX, OCI_DEFAULT)); status = OCIStmtExecute(mysvchp, stmthp, myerrhp, 1, 0, NULL, NULL,
OCI_DEFAULT); if (status && status != OCI_SUCCESS_WITH_INFO)
{
OCIHandleFree((dvoid*)myenvhp, OCI_HTYPE_ENV);
return -1;
}
printf("insert second\n");
OCITransRollback(mysvchp, myerrhp, (ub4) 0);
printf("rool back\n");
printf("end!\n");
OCISessionEnd(mysvchp, myerrhp, myusrhp, OCI_DEFAULT);
OCIServerDetach(mysrvhp, myerrhp, OCI_DEFAULT);
OCIHandleFree((void*)myenvhp, 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");    
printf("OCI Success: %s\n", m_s_szErr);
        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:
printf("OCI default\n");
        break;
    }
    if (lStatus != OCI_SUCCESS && lStatus != OCI_SUCCESS_WITH_INFO)
    {
        return 0;  //确实有错误
    } 
    else 
    {
        return 1;  //没有检查到错误
    }
}

解决方案 »

  1.   

    通过oci连接数据库,可以获得表结构的信息,例如对于表test("id" INTERGER,"num" INTERGER)可以获得表有两列,两列的数据结构分别为SQLT_INT,但是希望读取表结构的表项信息时总是为空,都是返回OCI_NO_DATA,但是表结构中是有几项信息的,请问是为什么?
    -------------------------
       这个问题见过,一般是批量获取数据时,你想获取100条,而实际上只有10条,就出现楼主说的错误,其实数据已在缓冲区里了,
       所以还要用下面的函数获取实际数量:
         //获取实际上fetch出来的记录总数
            nret = OCIAttrGet( m_pFStmthp, OCI_HTYPE_STMT, ( dvoid* )&fetchnum,
                (ub4 *)0, OCI_ATTR_ROWS_FETCHED, m_pFErrorhp );
       再循环获取每条数据....