OCIBindDynamics вешает сокет
У меня есть код, который я использую для привязки ввода / вывода, но у меня нет результата или результата None. Для реализации использую код из oci / examples
Я пробую использовать код OCI/ примеров "cdemodr1.c", я пишу свой собственный cbf_get_data. И используйте OCIBindDynamics после выполнения запроса.
static void** outputbufer; // buf for output
static ub4*** outputsizes;// buf for output sizes
static short*** outind; // indicator buf. For output sizes
uint32_t colsize; // buf for column size. We need it for cbf_get_data
uint32_t bindsize; // buf for bind size. We need it for cbf_get_data
uint16_t cursorid; // buf for cursor. We need it for cdf_get_data calls
static ub2*** rc; /* return codes */
static ub2** rowsret; // rows return for BindDynamics
int conn_dynamic(uint16_t id,void** buf,ub4*** sizes,short*** indbuf,ub2** rowsbuf){
int state = 1;
//uint32_t buffsize = 1* 1024;
/*void *outsize = 0;
uint32_t *outbuf = malloc(buffsize);*/
uint32_t collcount=0;
conn_colcount(id,&collcount);
colsize = collcount;
ub4 position[collcount];
uint32_t inoutbindcount=0;
cursorid = id;
uint32_t pos;
//void *data = 0;
//
outputbufer = malloc(sizeof (void*) * collcount);
if (state==1)
state = conn_bindoutcount(id, &inoutbindcount);
bindsize = inoutbindcount;
outputsizes= malloc(sizeof(ub4**)*collcount);
uint16_t i = 0;
for(; i<collcount;++i){
outputsizes[i]=malloc(sizeof(ub4*)*inoutbindcount);
uint16_t j = 0;
for(; j<inoutbindcount;++j)
{
outputsizes[i][j] = malloc(sizeof(ub4));
}
}
outind = malloc(sizeof(short**)* collcount);
for(i=0; i<collcount;++i){
outind[i]=malloc(sizeof(short*)*inoutbindcount);
uint16_t j = 0;
for(;j<inoutbindcount;++j)
{
outind[i][j]=malloc(sizeof(short));
}
}
rc = malloc(sizeof(ub2**)* collcount);
for(i=0; i<collcount;++i){
rc[i]=malloc(sizeof(ub2*)*inoutbindcount);
uint16_t j = 0;
for(;j<inoutbindcount;++j)
{
rc[i][j]=malloc(sizeof(ub2));
}
}
rowsret = malloc(sizeof(ub2)*inoutbindcount);
for ( pos = 0; pos < inoutbindcount && state == 1; ++pos){
state = OCIBindDynamic((connection.statements[id].outbinds[pos].handle),
connection.errhp,
(dvoid*) &position[pos],cbf_no_data,
(dvoid*)&position[pos],cbf_get_data);
}
buf = outputbufer;
sizes = outputsizes;
indbuf = outind;
rowsbuf = rowsret;
if (state != 0) return 0;
else return 1;
}
/* dummy callback that binds no data */
sb4 cbf_no_data(dvoid *ctxp, OCIBind *bindp, ub4 iter, ub4 index,
dvoid **bufpp, ub4 *alenpp, ub1 *piecep, dvoid **indpp) {
*bufpp = (dvoid *) 0;
*alenpp = 0;
*indpp = (dvoid *) 0;
*piecep = OCI_ONE_PIECE;
return OCI_CONTINUE;
}
/* callback to stash the returned data */
sb4 cbf_get_data(dvoid *ctxp, OCIBind *bindp, ub4 iter, ub4 index,
dvoid **bufpp, ub4 **alenp, ub1 *piecep,
dvoid **indpp, ub2 **rcodepp)
{
/*
* This is the callback function that is called to receive the OUT
* bind values for the bind variables in the RETURNING clause
*/
uint32_t bufsize= 1*1024;
static ub4 rows = 0;
ub4 pos = *((ub4 *)ctxp);
/* For each iteration the OCI_ATTR_ROWS_RETURNED tells us the number
* of rows returned in that iteration. So we can use this information
* to dynamically allocate storage for all the returned rows for that
* bind.
*/
if (index == 0)
{
(void) OCIAttrGet((CONST dvoid *)bindp, OCI_HTYPE_BIND, (dvoid *)&rows,
(ub4 *) sizeof(ub4), OCI_ATTR_ROWS_RETURNED,connection.errhp);
ub2 tmp = (ub2)rows;
rowsret[iter] = &tmp;
/* Dynamically allocate storage */
if (alloc_buffer(pos, iter, rows))
return OCI_ERROR;
}
/*Provide the address of the storage where the data is to be returned */
uint16_t type;
conn_outdatatype(cursorid, pos, &type);
uint32_t size;
switch (type) {
case SQLT_STR: //EBT_NULL
*bufpp = (dvoid *)outputbufer[iter];
break;
case SQLT_FLT:
*bufpp = (dvoid *)(&outputbufer[iter]);
break;
case SQLT_INT:
*bufpp = (dvoid *) outputbufer[iter];
break;
case SQLT_RSET:
*bufpp = (dvoid *) outputbufer[iter];
case SQLT_BLOB:
case SQLT_CLOB:
*bufpp = (dvoid *) outputbufer[iter];
break;
default:
*bufpp = (dvoid *) 0;
*alenp = (ub4 *) 0;
}
*piecep = OCI_ONE_PIECE;
/* provide address of the storage where the indicator will be returned */
outind[pos][iter][index] = 0;
*indpp = (dvoid *) &outind[pos][iter][index];
/* provide address of the storage where the return code will be returned */
rc[pos][iter][index] = 0;
*rcodepp = &rc[pos][iter][index];
/*
* provide address of the storage where the actual length will be
* returned
*/
*alenp = &outputsizes[pos][iter][index];
return OCI_CONTINUE;
}
sword alloc_buffer(ub4 pos, ub4 iter, ub4 rows)
{ // iter rows left over from Oracle implementation
uint16_t type=0;
uint32_t size=0;
// int16_t ind;
conn_outdatasize(cursorid, pos, &size);
conn_outdatatype(cursorid, pos, &type);
switch (type) {
case SQLT_STR: //EBT_NULL
outputbufer[iter] = malloc(sizeof(size));
break;
case SQLT_FLT:
outputbufer[iter] = malloc(sizeof(size));
break;
case SQLT_INT:
outputbufer[iter] = malloc(sizeof(size));
break;
case SQLT_RSET:
outputbufer[iter] = malloc(sizeof(size));
case SQLT_BLOB:
case SQLT_CLOB:
outputbufer[iter] = malloc(sizeof(size));
break;
default:
return OCI_ERROR;//we dont know about type specifiers, protocol may be broken
}
outind[pos][iter] = (short *) malloc(rows * sizeof(short));
outputsizes[pos][iter] = (ub4 *) malloc(rows * sizeof(ub4));
return OCI_SUCCESS;
}
Я пробую тест PL/SQL
`Begin :a := :b end;`
:a = "123":b = "abc"
ожидаемый результат: abc abc мой результат Нет, Нет