之前可能已经提出这个问题,所以如果重复这一点,我很抱歉。如果你可以链接到我能找到答案的地方,我会非常感激。我已经环顾了其他答案并在Google上,但似乎没有任何效果。 所以......
我在Oracle 11g中有一个存储的prodecure(我无法更改),我必须使用OCI(这里没有选择)。
存储过程声明如下:
PROCEDURE GetEmployee(EID IN NUMBER, rcursor IN OUT cursor_type);
如何在C中调用它?
我尝试使用the OCI example here作为基础,修改它:
char * query = "DECLARE \
EID NUMBER; \
RCURSOR CORP.EMPASSIST.cursor_type; \
BEGIN \
EID:= NULL; \
RCURSOR := NULL; \
EMPASSIST.GetEmployee( EID=> EID, RCURSOR => RCURSOR ); \
:RCURSOR := RCURSOR; --<-- Cursor \
END;";
OCIError * db_error;
OCIStmt * statement;
OCIEnv * environment;
OCIServer * server;
OCISession * session;
OCISvcCtx * service;
OCIBind * cursor_bind;
OCIBind * eid_bind;
OCIStmt * cursor_stm;
OCIStmt * eid_stm;
retval += OCIStmtPrepare(statement, db_error, (OraText *) query, strlen(query), OCI_NTV_SYNTAX, OCI_DEFAULT);
retval += OCIHandleAlloc(environment, (void **) &eid_stm, OCI_HTYPE_STMT, 0, NULL);
retval += OCIHandleAlloc(environment, (void **) &cursor_stm, OCI_HTYPE_STMT, 0, NULL);
retval += OCIBindByPos(statement, &eid_bind, db_error, 1, &eid_stm, 0, SQLT_NUM, NULL, 0, NULL, 0, 0, OCI_DEFAULT);
retval += OCIBindByPos(statement, &cursor_bind, db_error, 2, &cursor_stm, 0, SQLT_RSET, NULL, 0, NULL, 0, 0, OCI_DEFAULT);
retval += OCIStmtExecute(service, statement, db_error, 1, 0, NULL, NULL, OCI_COMMIT_ON_SUCCESS);
但这似乎对我不起作用。所有的句柄分配似乎都运行得很好。没有错误。
但是,它在OCIStmtExecute
步骤失败了。之后我必须使用BindByPos,它们也会失败,但我猜这是因为语句执行失败。
请帮忙!
============================================ ==============================
修正:在答案中发帖以防其他人
答案 0 :(得分:0)
如果你发布实际错误会有所帮助。
然而,与命名数据类型一样,绑定REF的过程分为两步。首先,调用OCIBindByName()或OCIBindByPos(),然后调用OCIBindObject()。
使用SQLT_REF数据类型绑定REF。使用SQLT_REF时,绑定的程序变量必须是OCIRef *。
类型使用继承和REF可替代性,您可以将REF值绑定到期望REF到超类型的子类型实例。
答案 1 :(得分:0)
更改:
char * query = "DECLARE \
EID NUMBER; \
RCURSOR CORP.EMPASSIST.cursor_type; \
BEGIN \
EID:= NULL; \
RCURSOR := NULL; \
EMPASSIST.GetEmployee( EID=> EID, RCURSOR => RCURSOR ); \
:RCURSOR := RCURSOR; --<-- Cursor \
END;";
到
int eid = /* whatever value */;
char * query_template = "CALL EMPASSIST.GetEmployee(%d, :RCURSOR)";
char query[1023] = {'\0'};
snprintf(query, sizeof(query) - 1, query_template, eid);
将其余部分改为:
OCIError * db_error;
OCIStmt * statement;
OCIEnv * environment;
OCISvcCtx * service;
OCIBind * cursor_bind;
OCIStmt * cursor_stm;
retval += OCIHandleAlloc(environment, (void **) &statement, OCI_HTYPE_STMT, 0, NULL);
retval += OCIStmtPrepare(statement, db_error, (OraText *) query, strlen(query), OCI_NTV_SYNTAX, OCI_DEFAULT);
retval += OCIHandleAlloc(environment, (void **) &cursor_stm, OCI_HTYPE_STMT, 0, NULL);
retval += OCIBindByName(statement, &cursorbind, db_error, (OraText *) ":RCURSOR", strlen(":RCURSOR"), &cursor, 0, SQLT_RSET, 0, 0, 0, 0, 0, OCI_DEFAULT);
retval += OCIStmtExecute(service, statement, db_error, 1, 0, NULL, NULL, OCI_COMMIT_ON_SUCCESS);