OCIBindDynamics вешает сокет - PullRequest
       26

OCIBindDynamics вешает сокет

0 голосов
/ 17 октября 2019

У меня есть некоторый код, который я использую для привязки in / out, но у меня нет какого-либо результата или результата None. Для реализации я использую код из oci / examples

. Я пытаюсь использовать OCI / examples code "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 мой результат Нет,None

...