Problem when binding output stored procedures
Open source C and C++ library for accessing Oracle Databases
Brought to you by:
vince_del_paris
Hi
I found you library very good, and i´m planning to use on an new project.
this small procedure
create or replace
procedure test3
(
param1 out varchar2
) as
begin
param1:='Hi world';
end test3;
never show hi world on screen
this is the code i tested
int main(void)
{
OCI_Connection cn;
OCI_Statement st;
OCI_Resultset *rs ;
int code = 22; int code2 = 2; if (!OCI_Initialize(NULL, NULL, OCI_ENV_DEFAULT)) return EXIT_FAILURE; cn = OCI_ConnectionCreate("culik3", "proprio", "proprio", OCI_SESSION_DEFAULT); st = OCI_StatementCreate(cn); printf( "%i\n",OCI_Prepare(st, "BEGIN test3(:22); END; ")); printf( "%i\n", OCI_SetBindMode( st,OCI_BIND_BY_POS )) ; printf( "%i\n", OCI_RegisterString(st, ":1",30)); printf( "%i\n", OCI_Execute(st)); rs = OCI_GetResultset(st); /* print resultset content */ while (OCI_FetchNext(rs))
{
printf("> String : %s", OCI_GetString(rs, 1));
}
OCI_Commit(cn); OCI_Cleanup(); return EXIT_SUCCESS;
}
Debugging ocilib sources i found the problem here
boolean OCI_DefineIsDataNotNull
(
OCI_Define *def
)
{
boolean res = FALSE;
if ((def != NULL) && (def->rs->row_cur > 0)) <------ ***Here the problem, def->rs->row_cur is 0 for executing this procedure*** { OCIInd ind = OCI_IND_NULL; if (def->col.type == OCI_CDT_OBJECT) { ind = * (OCIInd *) def->buf.obj_inds[def->rs->row_cur-1]; } else { ind = ((OCIInd *) (def->buf.inds))[def->rs->row_cur-1]; } res = (ind != OCI_IND_NULL); } return res;
}
Regards
Luiz Rafael Culik
Anonymous
HI
just for complement previus message.
Also the OCI_Resultset row_cur field is keeped as 0 , so the call to OCI_FetchNext will close the fetch since rs->row_abs and rs->row_count is both 0, making OCI_GetXXXX Fail
Regards
Luiz
Hello,
It does not work because you're not using the intended method for achieving what you want to do.
Before deeping in source code, take a bit of time reading on the documentation.
OCi_RegisterXXX() calls must be used only for supporting Oracle SQL "Returning into" clause.
When performing regular binding, you must use OCI_BindXXX() calls and must not use resultsets...
Another thing, you declared your precedure "test" taking an out string parameter.
But in your C code, you passing a bind string ":22" and tehn declare a bind ":1"... It cannot work.
Thus here is the right (and much simplier) way to do what you want :
Hi Vincent
Thanks for answer, but as I know for positional binds the name of parametere dont matter.
So for an stored procedure with output cursor, i can use this example bellow safely, correct
OCI_Statement* st2 = OCI_StatementCreate(cn);
Regards
Luiz