简体   繁体   English

Oracle OCI OCIStmtFetch2挂起光标C ++

[英]Oracle OCI OCIStmtFetch2 hangs cursor C++

My code hangs when I try to iterate over a cursor. 当我尝试遍历游标时,我的代码挂起。 The execute statement returns approx 800k results (when I run in sqlplus). execute语句返回大约800k的结果(当我在sqlplus中运行时)。 When I do something similar calling a simpler stored procedure with 20 results it returns instantly. 当我做类似的事情调用具有20个结果的简单存储过程时,它会立即返回。 I have left the program hanging for over 12 hours and still not returned. 我已将该程序挂起超过12个小时,但仍未返回。 I am using Oracle11g oci.lib, however when I tested with a 9i version of the lib it returned within 5 seconds. 我正在使用Oracle11g oci.lib,但是当我使用9i版本的lib进行测试时,它在5秒钟内返回。 Using 9i Oci is not an option for me (for reasons outside my control). 我无法使用9i Oci(出于无法控制的原因)。 I suspect the OCIStmtFetch2() call is pre-caching all the results first. 我怀疑OCIStmtFetch2()调用是先预缓存所有结果。 Is it possible to stop this and make the cursor useable? 是否可以停止此操作并使光标可用?

Stored procedure declaration: 存储过程声明:

CREATE OR REPLACE PROCEDURE FXT_TEST_CALL(CRESULTS OUT SYS_REFCURSOR) IS

and here is the code: (I've removed some boilerplate) 这是代码:(我已经删除了一些样板)

OCIStmt* pOciStatement;
OCIStmt* cursor;
OCIEnv* g_pOciEnvironment = NULL;
OCIServer* g_pOciServer = NULL;
OCISession* g_pOciSession = NULL;
OCISvcCtx* g_pOciServiceContext = NULL;
char* sqlCharArray = "BEGIN fxt.fxt_test_call(:refCursor ); END;";

answer = OCIInitialize(OCI_THREADED, NULL, NULL, NULL, NULL);
answer = OCIEnvInit(&g_pOciEnvironment, OCI_DEFAULT, 0, NULL);
answer = OCIHandleAlloc(g_pOciEnvironment, (void **)&pOciError, OCI_HTYPE_ERROR, 0, NULL);
answer = OCIHandleAlloc(g_pOciEnvironment, (void **)&g_pOciSession, OCI_HTYPE_SESSION, 0, NULL);
answer = OCIHandleAlloc(g_pOciEnvironment, (void **)&g_pOciServer, OCI_HTYPE_SERVER, 0, NULL);
answer = OCIHandleAlloc(g_pOciEnvironment, (void **)&g_pOciServiceContext, OCI_HTYPE_SVCCTX, 0, NULL);
answer = OCIServerAttach(g_pOciServer, pOciError, (unsigned char *)pConnectChar, strlen(pConnectChar),OCI_DEFAULT);
answer = OCIAttrSet(g_pOciSession, OCI_HTYPE_SESSION, (unsigned char *)pUsernameChar, strlen(pUsernameChar),OCI_ATTR_USERNAME, pOciError);
answer = OCIAttrSet(g_pOciSession, OCI_HTYPE_SESSION, (unsigned char *)pPasswordChar, strlen(pPasswordChar),OCI_ATTR_PASSWORD, pOciError);
answer = OCIAttrSet(g_pOciServiceContext, OCI_HTYPE_SVCCTX, g_pOciServer, 0, OCI_ATTR_SERVER, pOciError);
answer = OCIAttrSet(g_pOciServiceContext, OCI_HTYPE_SVCCTX, g_pOciSession, 0, OCI_ATTR_SESSION, pOciError);
answer = OCISessionBegin(g_pOciServiceContext, pOciError, g_pOciSession, OCI_CRED_RDBMS, OCI_DEFAULT);
answer = OCIHandleAlloc(g_pOciEnvironment, (void **)(&pOciStatement), OCI_HTYPE_STMT, 0, NULL);
answer = OCIStmtPrepare(pOciStatement, pOciError, (unsigned char *)sqlCharArray, strlen(sqlCharArray),OCI_NTV_SYNTAX, OCI_DEFAULT);
answer = OCIHandleAlloc(g_pOciEnvironment, (void **)(&cursor), OCI_HTYPE_STMT, 0, NULL);

answer = OCIBindByPos(pOciStatement,&pBind, pOciError, 1, &cursor, 0,SQLT_RSET, pIndicator2, 0,NULL, 0,0,OCI_DEFAULT);

OCINumber numTest;

answer = OCIStmtExecute(g_pOciServiceContext, pOciStatement, pOciError, 1, 0, NULL, NULL, OCI_COMMIT_ON_SUCCESS);
answer = OCIDefineByPos(cursor,&pOciDefine2, pOciError,1,&numTest,sizeof(OCINumber), SQLT_VNU, 0, 0, 0,OCI_DEFAULT);

// Program hangs here
while ((answer = OCIStmtFetch2(cursor,pOciError, 1,OCI_FETCH_NEXT,0,OCI_DEFAULT)) == 0)
{
    OCIAttrGet(cursor, OCI_HTYPE_STMT, (void*)&fetched, NULL, OCI_ATTR_ROWS_FETCHED, pOciError);
    long long newNum =  0;
    OCINumberToInt(pOciError, &numTest, sizeof(long long), OCI_NUMBER_SIGNED , &newNum);
}

Since this has been hanging around for a while with no answer I will reply for anyone curious, how I got around the situation. 由于问题已经徘徊了一段时间,所以我会回答任何好奇的人,我是如何解决这种情况的。 It was performing slow in an MFC debug build, so I ran in release mode and it worked (with a 2 minute pause). 在MFC调试版本中,它的执行速度很慢,所以我在发布模式下运行,并且正常工作(暂停2分钟)。

I still don't see what difference this would make, perhaps the libraries work differently in debug/release builds. 我仍然看不到会有什么不同,也许库在调试/发布版本中的工作方式有所不同。

Anyway, its not an issue anymore, for the moment at least. 无论如何,至少现在暂时不再是问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM