首页 > 解决方案 > 如何在一个变量中使用 OCIBindDynamic 来输入/输出?

问题描述

我的程序有一些关于 OCI/C 传输的代码。但是在将struct与OCIBindDynamics一起使用后我没有任何结果,我认为错误需要删除cbf_no_data,并在动态绑定后为输出变量添加BindByName。我不使用堆栈作为内存,所以在函数后删除数据时不会出现问题

 int conn_dynamic(uint16_t id,int pos,char *name,uint16_t type,uint32_t size,int16_t ind,void *data,uint16_t typein,uint32_t sizein,int16_t indin,void *datain,uint16_t mass_arr){
  CHECK_CURSOR_ID(id)
  int state = 1;
  cb_context_t* cbct = (cb_context_t*)malloc(sizeof(cb_context_t));
  cbct->cht.ptr = (void*)malloc(sizeof(void*));
  cbct->err     = connection.errhp;


  temp_arr_num = mass_arr;

  CHECK_IN_ID(id, pos)

  uint8_t bindbyname = 1;
  char bindname[65536];
  uint32_t bindpos;

  if (name[0] >= '0' && name[0] <= '9') {
    bindbyname = 0;
    bindpos = atoi(name);
  } else {
    bindname[0] = ':';
    strcpy(bindname + 1, name);
  }


  connection.statements[id].inbinds[pos].type = typein;
  connection.statements[id].inbinds[pos].ind = indin;
   memcpy(connection.statements[id].inbinds[pos].ptr, datain, sizein);
  if (typein == SQLT_CLOB || typein == SQLT_BLOB) {
    assert(connection.statements[id].inbinds[pos].lob == NULL);
    OCI_CALL(OCIDescriptorAlloc(connection.envhp, (void **)&connection.statements[id].inbinds[pos].lob, OCI_DTYPE_LOB, 0, 0));
    OCI_CALL(OCILobCreateTemporary(connection.svchp, connection.errhp, connection.statements[id].inbinds[pos].lob, (ub2)OCI_DEFAULT, OCI_DEFAULT,
                                   (typein == SQLT_CLOB)?OCI_TEMP_CLOB:OCI_TEMP_BLOB, OCI_ATTR_NOCACHE, OCI_DURATION_SESSION));
    OCI_CALL(OCILobOpen(connection.svchp, connection.errhp, connection.statements[id].inbinds[pos].lob, OCI_LOB_READWRITE));
    uint32_t amtp = sizein;
    OCI_CALL(OCILobWrite(connection.svchp, connection.errhp, connection.statements[id].inbinds[pos].lob, &amtp, 1, datain, sizein, OCI_ONE_PIECE, 0, 0, 0, SQLCS_IMPLICIT));

    if (bindbyname) {
      OCI_CALL(OCIBindByName(connection.statements[id].handle, &(connection.statements[id].inbinds[pos].handle), connection.errhp, (OraText *) name, strlen(name),
                             &(connection.statements[id].inbinds[pos].lob), 0, typein, 0, 0, 0, 0, 0, OCI_DATA_AT_EXEC));
    } else {
      OCI_CALL(OCIBindByPos(connection.statements[id].handle, &(connection.statements[id].inbinds[pos].handle), connection.errhp, bindpos,
                            &(connection.statements[id].inbinds[pos].lob), 0, typein, 0, 0, 0, 0, 0, OCI_DATA_AT_EXEC));
    }
  } else {
    if (!(connection.statements[id].inbinds[pos].ptr = malloc(sizein))) {                 //create temporary storage for value
      connection.error.code = 301;
      strcpy(connection.error.msg, "Out of memory");
      return -1;
    }


//    if (bindbyname) {
//      OCI_CALL(OCIBindByName(connection.statements[id].handle, &(connection.statements[id].inbinds[pos].handle), connection.errhp, (OraText *) name, strlen(name),
//                             &(connection.statements[id].inbinds[pos].ptr), sizein, typein, &connection.statements[id].inbinds[pos].ind, 0, 0, 0, 0, OCI_DATA_AT_EXEC));
//    } else {
//      OCI_CALL(OCIBindByPos(connection.statements[id].handle, &(connection.statements[id].inbinds[pos].handle), connection.errhp, bindpos,
//                            &(connection.statements[id].inbinds[pos].ptr), sizein, typein, &connection.statements[id].inbinds[pos].ind, 0, 0, 0, 0, OCI_DATA_AT_EXEC));
//    }
 }
  uint16_t oratype=0;
  WRITELOG(params,LDEBUG1,"TYPE IN BIND %d \n", type);
  switch (type) {
    case 2:{
        oratype = SQLT_INT;
        OCIBindDynamic(connection.statements[id].outbinds[pos].handle,connection.errhp,(dvoid*)cbct,cbf_no_data,(dvoid*)cbct,cbf_get_numeric_data);
        break;
      }
    case 3:{
        oratype = SQLT_FLT;
        OCIBindDynamic(connection.statements[id].outbinds[pos].handle,connection.errhp,(dvoid*)cbct,cbf_no_data,(dvoid*)cbct,cbf_get_numeric_data);

        break;
      }
    case 1:
    case 4:
    case 5:
    {
      if (type == 1){
        oratype = SQLT_STR;
        WRITELOG(params,LDEBUG1,"call str\n");
        OCI_CALL(OCIBindDynamic(connection.statements[id].outbinds[pos].handle,connection.errhp,(dvoid*)cbct,cbf_no_data,(dvoid*)cbct,cbf_get_string));

        }
      if (type == 5){ oratype = SQLT_CLOB;
        OCIBindDynamic(connection.statements[id].outbinds[pos].handle,connection.errhp,(dvoid*)cbct,cbf_no_data,(dvoid*)cbct,cbf_get_clob_data);
      }
      if (type == 4){
          oratype = SQLT_BLOB;
        OCIBindDynamic(connection.statements[id].outbinds[pos].handle,connection.errhp,(dvoid*)cbct,cbf_no_data,(dvoid*)cbct,cbf_get_blob_data);
      break;}
    case 6:{
        oratype = SQLT_RSET;
        OCIBindDynamic(connection.statements[id].outbinds[pos].handle,connection.errhp,(dvoid*)cbct,cbf_no_data,(dvoid*)cbct,cbf_ref_cursor);
      break;}
    }
    default:
      return -1;
    }
    printf("error here??");
    out_array[temp_arr_num]->type = oratype;
    out_array[temp_arr_num]->pos = pos;

    printf("No");
  //it's not a magic numbers. See outputbind in commands.c



  cursorid = id;


  //WRITE LOG HERE
  return 1;

}

所以我没有输出绑定,程序尝试获取变量。例如 cbf_get_string

sb4 cbf_get_string(dvoid *ctxp, OCIBind *bindp, ub4 iter, ub4 index,
         dvoid **bufpp, ub4 **alenp, ub1 *piecep,
         dvoid **indpp, ub2 **rcodepp) {

  cb_context_t* cbct = (cb_context_t*)ctxp;
  ub4    pos = *((ub4 *)ctxp);
  /* find out how many rows we are expecting */
  if (index == 0) {
    int rows = 0;
    OCIAttrGet((dvoid*)bindp, OCI_HTYPE_BIND, (dvoid*)&rows, (ub4*)sizeof(int), OCI_ATTR_ROWS_RETURNED, cbct->err);
    int sz = rows * sizeof(out_string_t);
    void* rs = (void*)malloc(sz);
    memcpy(cbct->cht.ptr, &rs, sizeof(void*)); /* ptr is now a pointer to a pointer */
#ifdef DEBUG
    char dbuf[256]; snprintf(dbuf, 255, "cbf_get_string: rows=%d rs=%p cbct->cht.ptr=%p bytes=%d", rows, rs, *(void**)cbct->cht.ptr, sz); debug(dbuf);
#endif
  }

  out_string_t* offset = (out_string_t*) ((*(void**)cbct->cht.ptr) + (index * sizeof(out_string_t)));
  *indpp =   (dvoid*)&offset->indicator;
  *rcodepp = (dvoid*)&offset->rc;
  *bufpp =   (dvoid*)&offset->bufpp;
  int size = sizeof(bufpp);

  offset->alenp =  size;
  *alenp =   (dvoid*)&offset->alenp;
  *piecep = OCI_ONE_PIECE;
  out_array[temp_arr_num]->ptr = cbct->cht.ptr;
  out_array[temp_arr_num]->index = index;
  WRITELOG(params,LDEBUG1,"string in bind %s \n", *(offset->bufpp));
  return OCI_CONTINUE;
}

你能告诉我,我哪里错了吗?因为我不能显示一些错误。我尝试只将“a”绑定到输入,将“a”绑定到输出。例如“Begin :a := :b End; 我需要查看 a

标签: coracleoracle-call-interface

解决方案


推荐阅读